summaryrefslogtreecommitdiff
path: root/gnuradio-core/src/python
diff options
context:
space:
mode:
Diffstat (limited to 'gnuradio-core/src/python')
-rw-r--r--gnuradio-core/src/python/build_utils.py226
-rw-r--r--gnuradio-core/src/python/build_utils_codes.py52
-rw-r--r--gnuradio-core/src/python/gnuradio/CMakeLists.txt38
-rw-r--r--gnuradio-core/src/python/gnuradio/__init__.py12
-rw-r--r--gnuradio-core/src/python/gnuradio/ctrlport/CMakeLists.txt112
-rw-r--r--gnuradio-core/src/python/gnuradio/ctrlport/GrDataPlotter.py428
-rw-r--r--gnuradio-core/src/python/gnuradio/ctrlport/IceRadioClient.py102
-rw-r--r--gnuradio-core/src/python/gnuradio/ctrlport/__init__.py30
-rwxr-xr-xgnuradio-core/src/python/gnuradio/ctrlport/gr-ctrlport-curses268
-rwxr-xr-xgnuradio-core/src/python/gnuradio/ctrlport/gr-ctrlport-monitor721
-rwxr-xr-xgnuradio-core/src/python/gnuradio/ctrlport/gr-perf-monitor591
-rwxr-xr-xgnuradio-core/src/python/gnuradio/ctrlport/gr-perf-monitorx727
-rw-r--r--gnuradio-core/src/python/gnuradio/ctrlport/icon.pngbin1532 -> 0 bytes
-rw-r--r--gnuradio-core/src/python/gnuradio/ctrlport/monitor.py59
-rw-r--r--gnuradio-core/src/python/gnuradio/eng_notation.py74
-rw-r--r--gnuradio-core/src/python/gnuradio/eng_option.py63
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/CMakeLists.txt49
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/__init__.py39
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/exceptions.py27
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/gateway.py243
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/gr_threading.py35
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/gr_threading_23.py724
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/gr_threading_24.py793
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/hier_block2.py132
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/prefs.py127
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/pubsub.py153
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_feval.py110
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_kludged_imports.py39
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_tag_utils.py55
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/tag_utils.py54
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/top_block.py171
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr_unittest.py170
-rw-r--r--gnuradio-core/src/python/gnuradio/gr_xmlrunner.py387
-rw-r--r--gnuradio-core/src/python/gnuradio/gru/CMakeLists.txt26
-rw-r--r--gnuradio-core/src/python/gnuradio/gru/__init__.py37
-rw-r--r--gnuradio-core/src/python/gnuradio/gruimpl/CMakeLists.txt36
-rw-r--r--gnuradio-core/src/python/gnuradio/gruimpl/__init__.py1
-rw-r--r--gnuradio-core/src/python/gnuradio/gruimpl/daemon.py102
-rw-r--r--gnuradio-core/src/python/gnuradio/gruimpl/freqz.py344
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gruimpl/gnuplot_freqz.py102
-rw-r--r--gnuradio-core/src/python/gnuradio/gruimpl/hexint.py44
-rw-r--r--gnuradio-core/src/python/gnuradio/gruimpl/listmisc.py29
-rw-r--r--gnuradio-core/src/python/gnuradio/gruimpl/mathmisc.py33
-rw-r--r--gnuradio-core/src/python/gnuradio/gruimpl/msgq_runner.py82
-rw-r--r--gnuradio-core/src/python/gnuradio/gruimpl/os_read_exactly.py36
-rw-r--r--gnuradio-core/src/python/gnuradio/gruimpl/seq_with_cursor.py77
-rw-r--r--gnuradio-core/src/python/gnuradio/gruimpl/socket_stuff.py62
47 files changed, 0 insertions, 7822 deletions
diff --git a/gnuradio-core/src/python/build_utils.py b/gnuradio-core/src/python/build_utils.py
deleted file mode 100644
index cf58a97637..0000000000
--- a/gnuradio-core/src/python/build_utils.py
+++ /dev/null
@@ -1,226 +0,0 @@
-#
-# Copyright 2004,2009,2012 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-"""Misc utilities used at build time
-"""
-
-import re, os, os.path
-from build_utils_codes import *
-
-
-# set srcdir to the directory that contains Makefile.am
-try:
- srcdir = os.environ['srcdir']
-except KeyError, e:
- srcdir = "."
-srcdir = srcdir + '/'
-
-# set do_makefile to either true or false dependeing on the environment
-try:
- if os.environ['do_makefile'] == '0':
- do_makefile = False
- else:
- do_makefile = True
-except KeyError, e:
- do_makefile = False
-
-# set do_sources to either true or false dependeing on the environment
-try:
- if os.environ['do_sources'] == '0':
- do_sources = False
- else:
- do_sources = True
-except KeyError, e:
- do_sources = True
-
-name_dict = {}
-
-def log_output_name (name):
- (base, ext) = os.path.splitext (name)
- ext = ext[1:] # drop the leading '.'
-
- entry = name_dict.setdefault (ext, [])
- entry.append (name)
-
-def open_and_log_name (name, dir):
- global do_sources
- if do_sources:
- f = open (name, dir)
- else:
- f = None
- log_output_name (name)
- return f
-
-def expand_template (d, template_filename, extra = ""):
- '''Given a dictionary D and a TEMPLATE_FILENAME, expand template into output file
- '''
- global do_sources
- output_extension = extract_extension (template_filename)
- template = open_src (template_filename, 'r')
- output_name = d['NAME'] + extra + '.' + output_extension
- log_output_name (output_name)
- if do_sources:
- output = open (output_name, 'w')
- do_substitution (d, template, output)
- output.close ()
- template.close ()
-
-def output_glue (dirname):
- output_makefile_fragment ()
- output_ifile_include (dirname)
-
-def output_makefile_fragment ():
- global do_makefile
- if not do_makefile:
- return
-# overwrite the source, which must be writable; this should have been
-# checked for beforehand in the top-level Makefile.gen.gen .
- f = open (os.path.join (os.environ.get('gendir', os.environ.get('srcdir', '.')), 'Makefile.gen'), 'w')
- f.write ('#\n# This file is machine generated. All edits will be overwritten\n#\n')
- output_subfrag (f, 'h')
- output_subfrag (f, 'i')
- output_subfrag (f, 'cc')
- f.close ()
-
-def output_ifile_include (dirname):
- global do_sources
- if do_sources:
- f = open ('%s_generated.i' % (dirname,), 'w')
- f.write ('//\n// This file is machine generated. All edits will be overwritten\n//\n')
- files = name_dict.setdefault ('i', [])
- files.sort ()
- f.write ('%{\n')
- for file in files:
- f.write ('#include <%s>\n' % (file[0:-1] + 'h',))
- f.write ('%}\n\n')
- for file in files:
- f.write ('%%include <%s>\n' % (file,))
-
-def output_subfrag (f, ext):
- files = name_dict.setdefault (ext, [])
- files.sort ()
- f.write ("GENERATED_%s =" % (ext.upper ()))
- for file in files:
- f.write (" \\\n\t%s" % (file,))
- f.write ("\n\n")
-
-def extract_extension (template_name):
- # template name is something like: GrFIRfilterXXX.h.t
- # we return everything between the penultimate . and .t
- mo = re.search (r'\.([a-z]+)\.t$', template_name)
- if not mo:
- raise ValueError, "Incorrectly formed template_name '%s'" % (template_name,)
- return mo.group (1)
-
-def open_src (name, mode):
- global srcdir
- return open (os.path.join (srcdir, name), mode)
-
-def do_substitution (d, in_file, out_file):
- def repl (match_obj):
- key = match_obj.group (1)
- # print key
- return d[key]
-
- inp = in_file.read ()
- out = re.sub (r"@([a-zA-Z0-9_]+)@", repl, inp)
- out_file.write (out)
-
-
-
-copyright = '''/* -*- c++ -*- */
-/*
- * Copyright 2003,2004 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 3, 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., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-'''
-
-def is_complex (code3):
- if i_code (code3) == 'c' or o_code (code3) == 'c':
- return '1'
- else:
- return '0'
-
-
-def standard_dict (name, code3, package='gr'):
- d = {}
- d['NAME'] = name
- d['NAME_IMPL'] = name+'_impl'
- d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper())
- d['GUARD_NAME_IMPL'] = 'INCLUDED_%s_%s_IMPL_H' % (package.upper(), name.upper())
- d['BASE_NAME'] = re.sub ('^' + package + '_', '', name)
- d['SPTR_NAME'] = '%s_sptr' % name
- d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten'
- d['COPYRIGHT'] = copyright
- d['TYPE'] = i_type (code3)
- d['I_TYPE'] = i_type (code3)
- d['O_TYPE'] = o_type (code3)
- d['TAP_TYPE'] = tap_type (code3)
- d['IS_COMPLEX'] = is_complex (code3)
- return d
-
-
-def standard_dict2 (name, code3, package):
- d = {}
- d['NAME'] = name
- d['BASE_NAME'] = name
- d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper())
- d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten'
- d['COPYRIGHT'] = copyright
- d['TYPE'] = i_type (code3)
- d['I_TYPE'] = i_type (code3)
- d['O_TYPE'] = o_type (code3)
- d['TAP_TYPE'] = tap_type (code3)
- d['IS_COMPLEX'] = is_complex (code3)
- return d
-
-def standard_impl_dict2 (name, code3, package):
- d = {}
- d['NAME'] = name
- d['IMPL_NAME'] = name
- d['BASE_NAME'] = name.rstrip("impl").rstrip("_")
- d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper())
- d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten'
- d['COPYRIGHT'] = copyright
- d['FIR_TYPE'] = "fir_filter_" + code3
- d['CFIR_TYPE'] = "fir_filter_" + code3[0:2] + 'c'
- d['TYPE'] = i_type (code3)
- d['I_TYPE'] = i_type (code3)
- d['O_TYPE'] = o_type (code3)
- d['TAP_TYPE'] = tap_type (code3)
- d['IS_COMPLEX'] = is_complex (code3)
- return d
diff --git a/gnuradio-core/src/python/build_utils_codes.py b/gnuradio-core/src/python/build_utils_codes.py
deleted file mode 100644
index 9ea96baae4..0000000000
--- a/gnuradio-core/src/python/build_utils_codes.py
+++ /dev/null
@@ -1,52 +0,0 @@
-#
-# Copyright 2004 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-def i_code (code3):
- return code3[0]
-
-def o_code (code3):
- if len (code3) >= 2:
- return code3[1]
- else:
- return code3[0]
-
-def tap_code (code3):
- if len (code3) >= 3:
- return code3[2]
- else:
- return code3[0]
-
-def i_type (code3):
- return char_to_type[i_code (code3)]
-
-def o_type (code3):
- return char_to_type[o_code (code3)]
-
-def tap_type (code3):
- return char_to_type[tap_code (code3)]
-
-
-char_to_type = {}
-char_to_type['s'] = 'short'
-char_to_type['i'] = 'int'
-char_to_type['f'] = 'float'
-char_to_type['c'] = 'gr_complex'
-char_to_type['b'] = 'unsigned char'
diff --git a/gnuradio-core/src/python/gnuradio/CMakeLists.txt b/gnuradio-core/src/python/gnuradio/CMakeLists.txt
deleted file mode 100644
index 9b75f20f33..0000000000
--- a/gnuradio-core/src/python/gnuradio/CMakeLists.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright 2010-2011 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-
-include(GrPython)
-
-add_subdirectory(gr)
-add_subdirectory(gru)
-add_subdirectory(gruimpl)
-
-if(ENABLE_GR_CTRLPORT)
-add_subdirectory(ctrlport)
-endif(ENABLE_GR_CTRLPORT)
-
-GR_PYTHON_INSTALL(FILES
- __init__.py
- eng_notation.py
- eng_option.py
- gr_unittest.py
- gr_xmlrunner.py
- DESTINATION ${GR_PYTHON_DIR}/gnuradio
- COMPONENT "core_python"
-)
diff --git a/gnuradio-core/src/python/gnuradio/__init__.py b/gnuradio-core/src/python/gnuradio/__init__.py
deleted file mode 100644
index d55dac79db..0000000000
--- a/gnuradio-core/src/python/gnuradio/__init__.py
+++ /dev/null
@@ -1,12 +0,0 @@
-"""
-GNU Radio is a free & open-source software development toolkit that provides signal processing blocks to implement software radios. It can be used with readily-available low-cost external RF hardware to create software-defined radios, or without hardware in a simulation-like environment. It is widely used in hobbyist, academic and commercial environments to support both wireless communications research and real-world radio systems.
-
-GNU Radio applications are primarily written using the Python programming language, while the supplied performance-critical signal-processing path is implemented in C++ using processor floating-point extensions, where available. Thus, the developer is able to implement real-time, high-throughput radio systems in a simple-to-use, rapid-application-development environment.
-
-While not primarily a simulation tool, GNU Radio does support development of signal processing algorithms using pre-recorded or generated data, avoiding the need for actual RF hardware.
-
-GNU Radio is licensed under the GNU General Public License (GPL) version 3. All of the code is copyright of the Free Software Foundation.
-"""
-
-# This file makes gnuradio a package
-# The docstring will be associated with the top level of the package.
diff --git a/gnuradio-core/src/python/gnuradio/ctrlport/CMakeLists.txt b/gnuradio-core/src/python/gnuradio/ctrlport/CMakeLists.txt
deleted file mode 100644
index 994e3a48cf..0000000000
--- a/gnuradio-core/src/python/gnuradio/ctrlport/CMakeLists.txt
+++ /dev/null
@@ -1,112 +0,0 @@
-# Copyright 2012 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-
-########################################################################
-include(GrPython)
-
-EXECUTE_PROCESS(
- COMMAND ${ICE_SLICE2PY} -I${CMAKE_SOURCE_DIR}/gnuradio-core/src/lib/runtime
- --output-dir=${CMAKE_BINARY_DIR}/gnuradio-core/src/python
- ${CMAKE_SOURCE_DIR}/gnuradio-core/src/lib/runtime/gnuradio.ice
-)
-
-EXECUTE_PROCESS(
- COMMAND ${ICE_SLICE2PY} -I${CMAKE_SOURCE_DIR}/gnuradio-core/src/lib/runtime
- --output-dir=${CMAKE_BINARY_DIR}/gnuradio-core/src/python
- ${CMAKE_SOURCE_DIR}/gnuradio-core/src/lib/runtime/frontend.ice
-)
-
-GR_PYTHON_INSTALL(
- FILES
- ${CMAKE_CURRENT_SOURCE_DIR}/__init__.py
- ${CMAKE_CURRENT_SOURCE_DIR}/IceRadioClient.py
- DESTINATION ${GR_PYTHON_DIR}/gnuradio/ctrlport/
- COMPONENT "core_python"
-)
-
-# We don't want to install these in the root Python directory, but we
-# aren't given a choice based on the way slice2py generates the
-# information.
-GR_PYTHON_INSTALL(
- FILES
- ${CMAKE_BINARY_DIR}/gnuradio-core/src/python/gnuradio_ice.py
- ${CMAKE_BINARY_DIR}/gnuradio-core/src/python/frontend_ice.py
- DESTINATION ${GR_PYTHON_DIR}
- COMPONENT "core_python"
-)
-
-GR_PYTHON_INSTALL(
- FILES
- ${CMAKE_CURRENT_BINARY_DIR}/GNURadio/__init__.py
- DESTINATION ${GR_PYTHON_DIR}/gnuradio/ctrlport/GNURadio
- COMPONENT "core_python"
-)
-
-GR_PYTHON_INSTALL(
- FILES
- ${CMAKE_CURRENT_BINARY_DIR}/GNURadio/Booter/__init__.py
- DESTINATION ${GR_PYTHON_DIR}/gnuradio/ctrlport/GNURadio/Booter
- COMPONENT "core_python"
-)
-
-GR_PYTHON_INSTALL(
- FILES
- ${CMAKE_CURRENT_BINARY_DIR}/GNURadio/Frontend/__init__.py
- DESTINATION ${GR_PYTHON_DIR}/gnuradio/ctrlport/GNURadio/Frontend
- COMPONENT "core_python"
-)
-
-install(
- FILES
- ${CMAKE_CURRENT_SOURCE_DIR}/icon.png
- DESTINATION ${GR_PYTHON_DIR}/gnuradio/ctrlport
- COMPONENT "core_python"
-)
-
-GR_PYTHON_INSTALL(
- FILES
- ${CMAKE_CURRENT_SOURCE_DIR}/GrDataPlotter.py
- ${CMAKE_CURRENT_SOURCE_DIR}/monitor.py
- DESTINATION ${GR_PYTHON_DIR}/gnuradio/ctrlport/
- COMPONENT "core_python"
-)
-
-GR_PYTHON_INSTALL(
- FILES
- ${CMAKE_CURRENT_SOURCE_DIR}/gr-ctrlport-monitor
- ${CMAKE_CURRENT_SOURCE_DIR}/gr-ctrlport-curses
- DESTINATION ${GR_RUNTIME_DIR}
- PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
- COMPONENT "core_python"
-)
-
-########################################################################
-# Handle the unit tests
-########################################################################
-if(ENABLE_GR_CTRLPORT)
- if(ENABLE_TESTING)
- include(GrTest)
- file(GLOB py_qa_test_files "qa_*.py")
- foreach(py_qa_test_file ${py_qa_test_files})
- get_filename_component(py_qa_test_name ${py_qa_test_file} NAME_WE)
- set(GR_TEST_TARGET_DEPS gruel gnuradio-core)
- GR_ADD_TEST(${py_qa_test_name} ${PYTHON_EXECUTABLE} ${py_qa_test_file})
- endforeach(py_qa_test_file)
- endif(ENABLE_TESTING)
-endif(ENABLE_GR_CTRLPORT)
diff --git a/gnuradio-core/src/python/gnuradio/ctrlport/GrDataPlotter.py b/gnuradio-core/src/python/gnuradio/ctrlport/GrDataPlotter.py
deleted file mode 100644
index 8597ca6497..0000000000
--- a/gnuradio-core/src/python/gnuradio/ctrlport/GrDataPlotter.py
+++ /dev/null
@@ -1,428 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2012,2013 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from gnuradio import gr
-from gnuradio import blocks
-from gnuradio import filter
-import sys, time
-
-try:
- from gnuradio import qtgui
- from PyQt4 import QtGui, QtCore
- import sip
-except ImportError:
- print "Error: Program requires PyQt4 and gr-qtgui."
- sys.exit(1)
-
-class GrDataPlotParent(gr.top_block, QtGui.QWidget):
- # Setup signals
- plotupdated = QtCore.pyqtSignal(QtGui.QWidget)
-
- def __init__(self, name, rate, pmin=None, pmax=None):
- gr.top_block.__init__(self)
- QtGui.QWidget.__init__(self, None)
-
- self._name = name
- self._npts = 500
- self._rate = rate
- self.knobnames = [name,]
-
- self.layout = QtGui.QVBoxLayout()
- self.setLayout(self.layout)
-
- self.setAcceptDrops(True)
-
- def _setup(self, nconnections):
- self.stop()
- self.wait()
-
- if(self.layout.count() > 0):
- # Remove and disconnect. Making sure no references to snk
- # remain so that the plot gets deleted.
- self.layout.removeWidget(self.py_window)
- self.disconnect(self.thr, (self.snk, 0))
- self.disconnect(self.src[0], self.thr)
- for n in xrange(1, self._ncons):
- self.disconnect(self.src[n], (self.snk,n))
-
- self._ncons = nconnections
- self._data_len = self._ncons*[0,]
-
- self.thr = blocks.throttle(self._datasize, self._rate)
- self.snk = self.get_qtsink()
-
- self.connect(self.thr, (self.snk, 0))
-
- self._last_data = []
- self.src = []
- for n in xrange(self._ncons):
- self.set_line_label(n, self.knobnames[n])
-
- self._last_data.append(int(self._npts)*[0,])
- self.src.append(self.get_vecsource())
-
- if(n == 0):
- self.connect(self.src[n], self.thr)
- else:
- self.connect(self.src[n], (self.snk,n))
-
- self.py_window = sip.wrapinstance(self.snk.pyqwidget(), QtGui.QWidget)
-
- self.layout.addWidget(self.py_window)
-
- def __del__(self):
- pass
-
- def close(self):
- self.snk.close()
-
- def qwidget(self):
- return self.py_window
-
- def name(self):
- return self._name
-
- def semilogy(self, en=True):
- self.snk.enable_semilogy(en)
-
- def dragEnterEvent(self, e):
- e.acceptProposedAction()
-
- def dropEvent(self, e):
- if(e.mimeData().hasFormat("text/plain")):
- data = str(e.mimeData().text())
-
- #"PlotData:{0}:{1}".format(tag, iscomplex)
- datalst = data.split(":::")
- tag = datalst[0]
- name = datalst[1]
- cpx = datalst[2] != "0"
-
- if(tag == "PlotData" and cpx == self._iscomplex):
- self.knobnames.append(name)
-
- # create a new qwidget plot with the new data stream.
- self._setup(len(self.knobnames))
-
- # emit that this plot has been updated with a new qwidget.
- self.plotupdated.emit(self)
-
- e.acceptProposedAction()
-
- def data_to_complex(self, data):
- if(self._iscomplex):
- data_r = data[0::2]
- data_i = data[1::2]
- data = [complex(r,i) for r,i in zip(data_r, data_i)]
- return data
-
- def update(self, data):
- # Ask GUI if there has been a change in nsamps
- npts = self.get_npts()
- if(self._npts != npts):
-
- # Adjust buffers to accomodate new settings
- for n in xrange(self._ncons):
- if(npts < self._npts):
- if(self._data_len[n] < npts):
- self._last_data[n] = self._last_data[n][0:npts]
- else:
- self._last_data[n] = self._last_data[n][self._data_len[n]-npts:self._data_len[n]]
- self._data_len[n] = npts
- else:
- self._last_data[n] += (npts - self._npts)*[0,]
- self._npts = npts
- self.snk.reset()
-
- if(self._stripchart):
- # Update the plot data depending on type
- for n in xrange(self._ncons):
- if(type(data[n]) == list):
- data[n] = self.data_to_complex(data[n])
- if(len(data[n]) > self._npts):
- self.src[n].set_data(data[n])
- self._last_data[n] = data[n][-self._npts:]
- else:
- newdata = self._last_data[n][-(self._npts-len(data)):]
- newdata += data[n]
- self.src[n].set_data(newdata)
- self._last_data[n] = newdata
-
- else: # single value update
- if(self._iscomplex):
- data[n] = complex(data[n][0], data[n][1])
- if(self._data_len[n] < self._npts):
- self._last_data[n][self._data_len[n]] = data[n]
- self._data_len[n] += 1
- else:
- self._last_data[n] = self._last_data[n][1:]
- self._last_data[n].append(data[n])
- self.src[n].set_data(self._last_data[n])
- else:
- for n in xrange(self._ncons):
- if(type(data[n]) != list):
- data[n] = [data[n],]
- data[n] = self.data_to_complex(data[n])
- self.src[n].set_data(data[n])
-
-
-
-class GrDataPlotterC(GrDataPlotParent):
- def __init__(self, name, rate, pmin=None, pmax=None, stripchart=False):
- GrDataPlotParent.__init__(self, name, rate, pmin, pmax)
-
- self._stripchart = stripchart
- self._datasize = gr.sizeof_gr_complex
- self._iscomplex = True
-
- self._setup(1)
-
- def stem(self, en=True):
- self.snk.enable_stem_plot(en)
-
- def get_qtsink(self):
- snk = qtgui.time_sink_c(self._npts, 1.0,
- self._name, self._ncons)
- snk.enable_autoscale(True)
- return snk
-
- def get_vecsource(self):
- return blocks.vector_source_c([])
-
- def get_npts(self):
- self._npts = self.snk.nsamps()
- return self._npts
-
- def set_line_label(self, n, name):
- self.snk.set_line_label(2*n+0, "Re{" + self.knobnames[n] + "}")
- self.snk.set_line_label(2*n+1, "Im{" + self.knobnames[n] + "}")
-
-
-class GrDataPlotterF(GrDataPlotParent):
- def __init__(self, name, rate, pmin=None, pmax=None, stripchart=False):
- GrDataPlotParent.__init__(self, name, rate, pmin, pmax)
-
- self._stripchart = stripchart
- self._datasize = gr.sizeof_float
- self._iscomplex = False
-
- self._setup(1)
-
- def stem(self, en=True):
- self.snk.enable_stem_plot(en)
-
- def get_qtsink(self):
- snk = qtgui.time_sink_f(self._npts, 1.0,
- self._name, self._ncons)
- snk.enable_autoscale(True)
- return snk
-
- def get_vecsource(self):
- return blocks.vector_source_f([])
-
- def get_npts(self):
- self._npts = self.snk.nsamps()
- return self._npts
-
- def set_line_label(self, n, name):
- self.snk.set_line_label(n, self.knobnames[n])
-
-
-class GrDataPlotterConst(GrDataPlotParent):
- def __init__(self, name, rate, pmin=None, pmax=None):
- GrDataPlotParent.__init__(self, name, rate, pmin, pmax)
-
- self._datasize = gr.sizeof_gr_complex
- self._stripchart = False
- self._iscomplex = True
-
- self._setup(1)
-
- def get_qtsink(self):
- snk = qtgui.const_sink_c(self._npts,
- self._name,
- self._ncons)
- snk.enable_autoscale(True)
- return snk
-
- def get_vecsource(self):
- return blocks.vector_source_c([])
-
- def get_npts(self):
- self._npts = self.snk.nsamps()
- return self._npts
-
- def scatter(self, en=True):
- if(en):
- self.snk.set_line_style(0, 0)
- else:
- self.snk.set_line_style(0, 1)
-
- def set_line_label(self, n, name):
- self.snk.set_line_label(n, self.knobnames[n])
-
-
-class GrDataPlotterPsdC(GrDataPlotParent):
- def __init__(self, name, rate, pmin=None, pmax=None):
- GrDataPlotParent.__init__(self, name, rate, pmin, pmax)
-
- self._datasize = gr.sizeof_gr_complex
- self._stripchart = True
- self._iscomplex = True
-
- self._npts = 2048
- self._wintype = filter.firdes.WIN_BLACKMAN_hARRIS
- self._fc = 0
-
- self._setup(1)
-
- def get_qtsink(self):
- snk = qtgui.freq_sink_c(self._npts, self._wintype,
- self._fc, 1.0,
- self._name,
- self._ncons)
- snk.enable_autoscale(True)
- return snk
-
- def get_vecsource(self):
- return blocks.vector_source_c([])
-
- def get_npts(self):
- self._npts = self.snk.fft_size()
- return self._npts
-
- def set_line_label(self, n, name):
- self.snk.set_line_label(n, self.knobnames[n])
-
-
-class GrDataPlotterPsdF(GrDataPlotParent):
- def __init__(self, name, rate, pmin=None, pmax=None):
- GrDataPlotParent.__init__(self, name, rate, pmin, pmax)
-
- self._datasize = gr.sizeof_float
- self._stripchart = True
- self._iscomplex = False
-
- self._npts = 2048
- self._wintype = filter.firdes.WIN_BLACKMAN_hARRIS
- self._fc = 0
-
- self._setup(1)
-
- def get_qtsink(self):
- snk = qtgui.freq_sink_f(self._npts, self._wintype,
- self._fc, 1.0,
- self._name,
- self._ncons)
- snk.enable_autoscale(True)
- return snk
-
- def get_vecsource(self):
- return blocks.vector_source_f([])
-
- def get_npts(self):
- self._npts = self.snk.fft_size()
- return self._npts
-
- def set_line_label(self, n, name):
- self.snk.set_line_label(n, self.knobnames[n])
-
-
-class GrTimeRasterF(GrDataPlotParent):
- def __init__(self, name, rate, pmin=None, pmax=None):
- GrDataPlotParent.__init__(self, name, rate, pmin, pmax)
-
- self._npts = 10
- self._rows = 40
-
- self._datasize = gr.sizeof_float
- self._stripchart = False
- self._iscomplex = False
-
- self._setup(1)
-
- def get_qtsink(self):
- snk = qtgui.time_raster_sink_f(1.0, self._npts, self._rows,
- [], [], self._name,
- self._ncons)
- return snk
-
- def get_vecsource(self):
- return blocks.vector_source_f([])
-
- def get_npts(self):
- self._npts = self.snk.num_cols()
- return self._npts
-
- def set_line_label(self, n, name):
- self.snk.set_line_label(n, self.knobnames[n])
-
-class GrTimeRasterB(GrDataPlotParent):
- def __init__(self, name, rate, pmin=None, pmax=None):
- GrDataPlotParent.__init__(self, name, rate, pmin, pmax)
-
- self._npts = 10
- self._rows = 40
-
- self._datasize = gr.sizeof_char
- self._stripchart = False
- self._iscomplex = False
-
- self._setup(1)
-
- def get_qtsink(self):
- snk = qtgui.time_raster_sink_b(1.0, self._npts, self._rows,
- [], [], self._name,
- self._ncons)
- return snk
-
- def get_vecsource(self):
- return blocks.vector_source_b([])
-
- def get_npts(self):
- self._npts = self.snk.num_cols()
- return self._npts
-
- def set_line_label(self, n, name):
- self.snk.set_line_label(n, self.knobnames[n])
-
-
-class GrDataPlotterValueTable:
- def __init__(self, uid, parent, x, y, xsize, ysize,
- headers=['Statistic Key ( Source Block :: Stat Name ) ',
- 'Curent Value', 'Units', 'Description']):
- # must encapsulate, cuz Qt's bases are not classes
- self.uid = uid
- self.treeWidget = QtGui.QTreeWidget(parent)
- self.treeWidget.setColumnCount(len(headers))
- self.treeWidget.setGeometry(x,y,xsize,ysize)
- self.treeWidget.setHeaderLabels(headers)
- self.treeWidget.resizeColumnToContents(0)
-
- def updateItems(self, knobs, knobprops):
- items = [];
- self.treeWidget.clear()
- for k, v in knobs.iteritems():
- items.append(QtGui.QTreeWidgetItem([str(k), str(v.value),
- knobprops[k].units,
- knobprops[k].description]))
- self.treeWidget.insertTopLevelItems(0, items)
diff --git a/gnuradio-core/src/python/gnuradio/ctrlport/IceRadioClient.py b/gnuradio-core/src/python/gnuradio/ctrlport/IceRadioClient.py
deleted file mode 100644
index 0964b5a4ba..0000000000
--- a/gnuradio-core/src/python/gnuradio/ctrlport/IceRadioClient.py
+++ /dev/null
@@ -1,102 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2012 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-import Ice, Glacier2
-from PyQt4 import QtGui, QtCore
-import sys, time, Ice
-from gnuradio import gr
-from gnuradio.ctrlport import GNURadio
-
-class IceRadioClient(Ice.Application):
- def __init__(self, parentClass):
- self.parentClass = parentClass
-
- def getRadio(self, host, port):
- radiostr = "gnuradio -t:tcp -h " + host + " -p " + port + " -t 3000"
- base = self.communicator().stringToProxy(radiostr).ice_twoway()
- radio = GNURadio.ControlPortPrx.checkedCast(base)
-
- if not radio:
- sys.stderr.write("{0} : invalid proxy.\n".format(args[0]))
- return None
-
- return radio
-
- def run(self,args):
- if len(args) < 2:
- print "useage: [glacierinstance glacierhost glacierport] host port"
- return
- if len(args) == 8:
- self.useglacier = True
- guser = args[1]
- gpass = args[2]
- ginst = args[3]
- ghost = args[4]
- gport = args[5]
- host = args[6]
- port = args[7]
- else:
- self.useglacier = False
- host = args[1]
- port = args[2]
-
- if self.useglacier:
- gstring = ginst + "/router -t:tcp -h " + ghost + " -p " + gport
- print "GLACIER: {0}".format(gstring)
-
- setrouter = Glacier2.RouterPrx.checkedCast(self.communicator().stringToProxy(gstring))
- self.communicator().setDefaultRouter(setrouter)
- defaultRouter = self.communicator().getDefaultRouter()
- #defaultRouter = self.communicator().stringToProxy(gstring)
- if not defaultRouter:
- print self.appName() + ": no default router set"
- return 1
- else:
- print str(defaultRouter)
- router = Glacier2.RouterPrx.checkedCast(defaultRouter)
- if not router:
- print self.appName() + ": configured router is not a Glacier2 router"
- return 1
-
- while True:
- print "This demo accepts any user-id / password combination."
- if not guser == '' and not gpass == '':
- id = guser
- pw = gpass
- else:
- id = raw_input("user id: ")
- pw = raw_input("password: ")
-
- try:
- router.createSession(id, pw)
- break
- except Glacier2.PermissionDeniedException, ex:
- print "permission denied:\n" + ex.reason
-
- radio = self.getRadio(host, port)
- if(radio is None):
- return 1
-
- app = QtGui.QApplication(sys.argv)
- ex = self.parentClass(radio, port, self)
- ex.show();
- app.exec_()
diff --git a/gnuradio-core/src/python/gnuradio/ctrlport/__init__.py b/gnuradio-core/src/python/gnuradio/ctrlport/__init__.py
deleted file mode 100644
index 031c3b424e..0000000000
--- a/gnuradio-core/src/python/gnuradio/ctrlport/__init__.py
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Copyright 2012 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 3, 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 this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-
-# The presence of this file turns this directory into a Python package
-
-import Ice, IcePy
-
-# import swig generated symbols into the ctrlport namespace
-#from ctrlport_swig import *
-from monitor import *
-
-# import any pure python here
-#import GNURadio
diff --git a/gnuradio-core/src/python/gnuradio/ctrlport/gr-ctrlport-curses b/gnuradio-core/src/python/gnuradio/ctrlport/gr-ctrlport-curses
deleted file mode 100755
index 1bee3b1a1e..0000000000
--- a/gnuradio-core/src/python/gnuradio/ctrlport/gr-ctrlport-curses
+++ /dev/null
@@ -1,268 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2012 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-import threading
-import curses
-import os, sys, time
-from optparse import OptionParser
-
-import Ice
-from gnuradio.ctrlport import GNURadio
-
-ENTER = chr(10)
-UP_ARROW = chr(65)
-DOWN_ARROW = chr(66)
-
-class modem_monitor(threading.Thread):
- def __init__(self, cb_live, cb_exit, interface):
- threading.Thread.__init__(self)
- self.cb_live = cb_live
- self.cb_exit = cb_exit
-
- self.running = True
-
- def __del__(self):
- rx.close()
-
- def run(self):
- while self.running:
- time.sleep(0.5)
-
- def shutdown(self):
- self.running = False
- self.rx.close()
-
- def cb(self,contents):
- (op, sep, payload) = contents.partition(":")
- if(op == "live"):
- print "live"
- self.cb_live(payload)
- elif(op == "exit"):
- self.cb_exit(payload)
- else:
- print "unknown op arrived! garbage on multicast adx?"
-
-class modem_window(threading.Thread):
- def __init__(self, locator):
- threading.Thread.__init__(self)
- self.locator = locator
-
- # curses init
- self.win = curses.newwin(30,100,4,4)
-
- # Ice/GRCP init
- self.comm = Ice.initialize()
- proxy = self.comm.stringToProxy(locator)
- self.radio = GNURadio.ControlPortPrx.checkedCast(proxy)
- self.updateKnobs()
-
- # GUI init
- self.running = True
- self.ssel = 0
- self.start()
- #self.updateGUI()
-
- # input loop
- while(self.running):
- self.getInput()
-
- # wait for update thread exit
- self.join()
-
- def updateKnobs(self):
- self.knobs = self.radio.get([])
-
- def getInput(self):
- a = self.win.getch()
- if(a <= 256):
- a = chr(a)
- if(a == 'q'):
- self.running = False
- elif(a == UP_ARROW):
- self.ssel = max(self.ssel-1, 0)
- self.updateGUI()
- elif(a == DOWN_ARROW):
- self.ssel = max(min(self.ssel+1, len(self.knobs.keys())-1),0)
- self.updateGUI()
- self.updateGUI()
-
- def updateGUI(self):
- self.win.clear()
- self.win.border(0)
- self.win.addstr(1, 2, "Modem Statistics :: %s"%(self.locator))
- self.win.addstr(2, 2, "---------------------------------------------------")
-
- maxnb = 0
- maxk = 0
- for k in self.knobs.keys():
- (nb,k) = k.split("::", 2)
- maxnb = max(maxnb,len(nb))
- maxk = max(maxk,len(k))
-
- offset = 3
- keys = self.knobs.keys()
- keys.sort()
- for k in keys:
- (nb,sk) = k.split("::", 2)
- v = self.knobs[k].value
- sv = str(v)
- if(len(sv) > 20):
- sv = sv[0:20]
- props = 0
- if(self.ssel == offset-3):
- props = props | curses.A_REVERSE
- self.win.addstr(offset, 2, "%s %s %s" % \
- (nb.rjust(maxnb," "), sk.ljust(maxk," "), sv),props)
- offset = offset + 1
- self.win.refresh()
-
- def run(self):
- while(self.running):
- self.updateKnobs()
- self.updateGUI()
- time.sleep(1)
-
-class monitor_gui:
- def __init__(self, interfaces, options):
-
- locator = None
-
- # Extract options into a locator
- if(options.host and options.port):
- locator = "{0} -t:{1} -h {2} -p {3}".format(
- options.app, options.protocol,
- options.host, options.port)
-
- # Set up GUI
- self.locators = {}
-
- self.mode = 0 # modem index screen (modal keyboard input)
- self.lsel = 0 # selected locator
- self.scr = curses.initscr()
- self.updateGUI()
-
- # Kick off initial monitors
- self.monitors = []
- for i in interfaces:
- self.monitors.append( modem_monitor(self.addModem, self.delModem, i) )
- self.monitors[-1].start()
-
- if not ((locator == None) or (locator == "")):
- self.addModem(locator)
-
- # wait for user input
- while(True):
- self.getInput()
-
- def addModem(self, locator):
- if(not self.locators.has_key(locator)):
- self.locators[locator] = {}
- self.locators[locator]["update_time"] = time.time()
- self.locators[locator]["status"] = "live"
-
- self.updateGUI();
-
- def delModem(self, locator):
- #if(self.locators.has_key(locator)):
- if(not self.locators.has_key(locator)):
- self.locators[locator] = {}
- self.locators[locator]["update_time"] = time.time()
- self.locators[locator]["status"] = "exit"
-
- self.updateGUI()
-
- def updateGUI(self):
- if(self.mode == 0): #redraw locators
- self.scr.clear()
- self.scr.border(0)
- self.scr.addstr(1, 2, " GRCP-Curses Modem Monitor :: (A)dd (R)efresh, (Q)uit, ...")
- for i in range(len(self.locators.keys())):
- locator = self.locators.keys()[i]
- lhash = self.locators[locator]
- #self.scr.addstr(3+i, 5, locator + str(lhash))
- props = 0
- if(self.lsel == i):
- props = props | curses.A_REVERSE
- self.scr.addstr(3+i, 5, locator + str(lhash), props)
- self.scr.refresh()
-
- def connectGUI(self):
- self.scr.clear()
- self.scr.addstr(1, 1, "Connect to radio:")
- locator = self.scr.getstr(200)
- self.addModem(locator)
- self.updateGUI()
-
- def getInput(self):
- a = self.scr.getch()
- self.scr.addstr(20, 2, "got key (%d) " % (int(a)))
- if(a <= 256):
- a = chr(a)
- if(a =='r'):
- self.updateGUI()
- elif(a == 'q'):
- self.shutdown()
- elif(a == 'a'):
- self.connectGUI()
- elif(a == UP_ARROW):
- self.lsel = max(self.lsel-1, 0)
- self.updateGUI()
- elif(a == DOWN_ARROW):
- self.lsel = max(min(self.lsel+1, len(self.locators.keys())-1),0)
- self.updateGUI()
- elif(a == ENTER):
- try:
- locator = self.locators.keys()[self.lsel]
- self.mode = 1
- mwin = modem_window(locator)
- self.mode = 0
- # pop up a new modem display ...
- self.updateGUI()
- except:
- pass
-
- def shutdown(self):
- curses.endwin()
- os._exit(0)
-
-if __name__ == "__main__":
- parser = OptionParser()
- parser.add_option("-H", "--host", type="string",
- help="Hostname of ControlPort server.")
- parser.add_option("-p", "--port", type="int",
- help="Port number of host's ControlPort endpoint.")
- parser.add_option("-i", "--interfaces", type="string",
- action="append", default=["lo"],
- help="Interfaces to use. [default=%default]")
- parser.add_option("-P", "--protocol", type="string", default="tcp",
- help="Type of protocol to use (usually tcp). [default=%default]")
- parser.add_option("-a", "--app", type="string", default="gnuradio",
- help="Name of application [default=%default]")
- (options, args) = parser.parse_args()
-
- if((options.host == None) ^ (options.port == None)):
- print "Please set both a hostname and a port number.\n"
- parser.print_help()
- sys.exit(1)
-
- mg = monitor_gui(options.interfaces, options)
-
diff --git a/gnuradio-core/src/python/gnuradio/ctrlport/gr-ctrlport-monitor b/gnuradio-core/src/python/gnuradio/ctrlport/gr-ctrlport-monitor
deleted file mode 100755
index e71cd92ab7..0000000000
--- a/gnuradio-core/src/python/gnuradio/ctrlport/gr-ctrlport-monitor
+++ /dev/null
@@ -1,721 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2012,2013 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from gnuradio import gr, ctrlport
-
-from PyQt4 import QtCore,Qt
-import PyQt4.QtGui as QtGui
-import os, sys, time
-
-import Ice
-from gnuradio.ctrlport.IceRadioClient import *
-from gnuradio.ctrlport.GrDataPlotter import *
-from gnuradio.ctrlport import GNURadio
-
-class RateDialog(QtGui.QDialog):
- def __init__(self, delay, parent=None):
- super(RateDialog, self).__init__(parent)
- self.gridLayout = QtGui.QGridLayout(self)
- self.setWindowTitle("Update Delay (ms)");
- self.delay = QtGui.QLineEdit(self);
- self.delay.setText(str(delay));
- self.buttonBox = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel)
- self.gridLayout.addWidget(self.delay);
- self.gridLayout.addWidget(self.buttonBox);
- self.buttonBox.accepted.connect(self.accept)
- self.buttonBox.rejected.connect(self.reject)
- def accept(self):
- self.done(1);
- def reject(self):
- self.done(0);
-
-class MAINWindow(QtGui.QMainWindow):
- def minimumSizeHint(self):
- return Qtgui.QSize(800,600)
-
- def __init__(self, radio, port, interface):
-
- super(MAINWindow, self).__init__()
- self.updateRate = 1000;
- self.conns = []
- self.plots = []
- self.knobprops = []
- self.interface = interface
-
- self.mdiArea = QtGui.QMdiArea()
- self.mdiArea.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
- self.mdiArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
- self.setCentralWidget(self.mdiArea)
-
- self.mdiArea.subWindowActivated.connect(self.updateMenus)
- self.windowMapper = QtCore.QSignalMapper(self)
- self.windowMapper.mapped[QtGui.QWidget].connect(self.setActiveSubWindow)
-
- self.createActions()
- self.createMenus()
- self.createToolBars()
- self.createStatusBar()
- self.updateMenus()
-
- self.setWindowTitle("GNU Radio Control Port Monitor")
- self.setUnifiedTitleAndToolBarOnMac(True)
-
- self.newCon(radio, port)
- icon = QtGui.QIcon(ctrlport.__path__[0] + "/icon.png" )
- self.setWindowIcon(icon)
-
- # Locally turn off ControlPort export from GR. This prevents
- # our GR-based plotters from launching their own ControlPort
- # instance (and possibly causing a port collision if one has
- # been specified).
- os.environ['GR_CONF_CONTROLPORT_ON'] = 'False'
-
- def setUpdateRate(self,nur):
- self.updateRate = int(nur);
- for c in self.conns:
- c.updateRate = self.updateRate;
- c.timer.setInterval(self.updateRate);
-
- def newCon(self, radio=None, port=None):
- child = MForm(radio, port, len(self.conns), self.updateRate, self)
- if(child.radio is not None):
- child.setWindowTitle(str(child.radio))
- self.mdiArea.addSubWindow(child)
- child.showMaximized()
- self.conns.append(child)
- self.plots.append([])
-
- def propertiesMenu(self, key, radio, uid):
- r = str(radio).split(" ")
- title = "{0}:{1}".format(r[3], r[5])
-
- props = radio.properties([key])
- pmin = props[key].min.value
- pmax = props[key].max.value
- if pmin == []:
- pmin = None
- else:
- pmin = 1.1*pmin
- if pmax == []:
- pmax = None
- else:
- pmax = 1.1*pmax
-
- # Use display option mask of item to set up available plot
- # types and default options.
- disp = self.knobprops[uid][key].display
- cplx = disp & gr.DISPOPTCPLX | disp & gr.DISPXY
- strip = disp & gr.DISPOPTSTRIP
- stem = disp & gr.DISPOPTSTEM
- log = disp & gr.DISPOPTLOG
- scatter = disp & gr.DISPOPTSCATTER
-
- def newUpdaterProxy():
- self.newUpdater(key, radio)
-
- def newPlotterFProxy():
- self.newPlotF(key, uid, title, pmin, pmax,
- log, strip, stem)
-
- def newPlotterCProxy():
- self.newPlotC(key, uid, title, pmin, pmax,
- log, strip, stem)
-
- def newPlotterConstProxy():
- self.newPlotConst(key, uid, title, pmin, pmax, scatter)
-
- def newPlotterPsdFProxy():
- self.newPlotPsdF(key, uid, title)
-
- def newPlotterPsdCProxy():
- self.newPlotPsdC(key, uid, title)
-
- def newPlotterRasterFProxy():
- self.newPlotRasterF(key, uid, title, pmin, pmax)
-
- def newPlotterRasterBProxy():
- self.newPlotRasterB(key, uid, title, pmin, pmax)
-
- menu = QtGui.QMenu(self)
- menu.setTitle("Item Actions")
- menu.setTearOffEnabled(False)
-
- # object properties
- menu.addAction("Properties", newUpdaterProxy)
-
- # displays available
- if(cplx == 0):
- menu.addAction("Plot Time", newPlotterFProxy)
- menu.addAction("Plot PSD", newPlotterPsdFProxy)
- menu.addAction("Plot Raster (real)", newPlotterRasterFProxy)
- #menu.addAction("Plot Raster (bits)", newPlotterRasterBProxy)
- else:
- menu.addAction("Plot Time", newPlotterCProxy)
- menu.addAction("Plot PSD", newPlotterPsdCProxy)
- menu.addAction("Plot Constellation", newPlotterConstProxy)
-
- menu.popup(QtGui.QCursor.pos())
-
- def newUpdater(self, key, radio):
- updater = UpdaterWindow(key, radio, None)
- updater.setWindowTitle("Updater: " + key)
- updater.setModal(False)
- updater.exec_()
-
- def newSub(self, e):
- tag = str(e.text(0))
- tree = e.treeWidget().parent()
- uid = tree.uid
- knobprop = self.knobprops[uid][tag]
-
- r = str(tree.radio).split(" ")
- title = "{0}:{1}".format(r[3], r[5])
- pmin = knobprop.min.value
- pmax = knobprop.max.value
- if pmin == []:
- pmin = None
- else:
- pmin = 1.1*pmin
- if pmax == []:
- pmax = None
- else:
- pmax = 1.1*pmax
-
- disp = knobprop.display
- if(disp & gr.DISPTIME):
- strip = disp & gr.DISPOPTSTRIP
- stem = disp & gr.DISPOPTSTEM
- log = disp & gr.DISPOPTLOG
- if(disp & gr.DISPOPTCPLX == 0):
- self.newPlotF(tag, uid, title, pmin, pmax,
- log, strip, stem)
- else:
- self.newPlotC(tag, uid, title, pmin, pmax,
- log, strip, stem)
-
- elif(disp & gr.DISPXY):
- scatter = disp & gr.DISPOPTSCATTER
- self.newPlotConst(tag, uid, title, pmin, pmax, scatter)
-
- elif(disp & gr.DISPPSD):
- if(disp & gr.DISPOPTCPLX == 0):
- self.newPlotPsdF(tag, uid, title)
- else:
- self.newPlotPsdC(tag, uid, title)
-
- def startDrag(self, e):
- drag = QtGui.QDrag(self)
- mime_data = QtCore.QMimeData()
-
- tag = str(e.text(0))
- tree = e.treeWidget().parent()
- knobprop = self.knobprops[tree.uid][tag]
- disp = knobprop.display
- iscomplex = (disp & gr.DISPOPTCPLX) or (disp & gr.DISPXY)
-
- if(disp != gr.DISPNULL):
- data = "PlotData:::{0}:::{1}".format(tag, iscomplex)
- else:
- data = "OtherData:::{0}:::{1}".format(tag, iscomplex)
-
- mime_data.setText(data)
- drag.setMimeData(mime_data)
-
- drop = drag.start()
-
- def createPlot(self, plot, uid, title):
- plot.start()
- self.plots[uid].append(plot)
-
- self.mdiArea.addSubWindow(plot)
- plot.setWindowTitle("{0}: {1}".format(title, plot.name()))
- self.connect(plot.qwidget(),
- QtCore.SIGNAL('destroyed(QObject*)'),
- self.destroyPlot)
-
- # when the plot is updated via drag-and-drop, we need to be
- # notified of the new qwidget that's created so we can
- # properly destroy it.
- plot.plotupdated.connect(self.plotUpdated)
-
- plot.show()
-
- def plotUpdated(self, q):
- # the plot has been updated with a new qwidget; make sure this
- # gets dies to the destroyPlot function.
- for i, plots in enumerate(self.plots):
- for p in plots:
- if(p == q):
- #plots.remove(p)
- #plots.append(q)
- self.connect(q.qwidget(),
- QtCore.SIGNAL('destroyed(QObject*)'),
- self.destroyPlot)
- break
-
- def destroyPlot(self, obj):
- for plots in self.plots:
- for p in plots:
- if p.qwidget() == obj:
- plots.remove(p)
- break
-
- def newPlotConst(self, tag, uid, title="", pmin=None, pmax=None,
- scatter=False):
- plot = GrDataPlotterConst(tag, 32e6, pmin, pmax)
- plot.scatter(scatter)
- self.createPlot(plot, uid, title)
-
- def newPlotF(self, tag, uid, title="", pmin=None, pmax=None,
- logy=False, stripchart=False, stem=False):
- plot = GrDataPlotterF(tag, 32e6, pmin, pmax, stripchart)
- plot.semilogy(logy)
- plot.stem(stem)
- self.createPlot(plot, uid, title)
-
- def newPlotC(self, tag, uid, title="", pmin=None, pmax=None,
- logy=False, stripchart=False, stem=False):
- plot = GrDataPlotterC(tag, 32e6, pmin, pmax, stripchart)
- plot.semilogy(logy)
- plot.stem(stem)
- self.createPlot(plot, uid, title)
-
- def newPlotPsdF(self, tag, uid, title="", pmin=None, pmax=None):
- plot = GrDataPlotterPsdF(tag, 32e6, pmin, pmax)
- self.createPlot(plot, uid, title)
-
- def newPlotPsdC(self, tag, uid, title="", pmin=None, pmax=None):
- plot = GrDataPlotterPsdC(tag, 32e6, pmin, pmax)
- self.createPlot(plot, uid, title)
-
- def newPlotRasterF(self, tag, uid, title="", pmin=None, pmax=None):
- plot = GrTimeRasterF(tag, 32e6, pmin, pmax)
- self.createPlot(plot, uid, title)
-
- def newPlotRasterB(self, tag, uid, title="", pmin=None, pmax=None):
- plot = GrTimeRasterB(tag, 32e6, pmin, pmax)
- self.createPlot(plot, uid, title)
-
- def update(self, knobs, uid):
- #sys.stderr.write("KNOB KEYS: {0}\n".format(knobs.keys()))
- for plot in self.plots[uid]:
- data = []
- for n in plot.knobnames:
- data.append(knobs[n].value)
- plot.update(data)
- plot.stop()
- plot.wait()
- plot.start()
-
- def setActiveSubWindow(self, window):
- if window:
- self.mdiArea.setActiveSubWindow(window)
-
-
- def createActions(self):
- self.newConAct = QtGui.QAction("&New Connection",
- self, shortcut=QtGui.QKeySequence.New,
- statusTip="Create a new file", triggered=self.newCon)
- #self.newAct = QtGui.QAction(QtGui.QIcon(':/images/new.png'), "&New Plot",
- self.newPlotAct = QtGui.QAction("&New Plot",
- self,
- statusTip="Create a new file", triggered=self.newPlotF)
-
- self.exitAct = QtGui.QAction("E&xit", self, shortcut="Ctrl+Q",
- statusTip="Exit the application",
- triggered=QtGui.qApp.closeAllWindows)
-
- self.closeAct = QtGui.QAction("Cl&ose", self, shortcut="Ctrl+F4",
- statusTip="Close the active window",
- triggered=self.mdiArea.closeActiveSubWindow)
-
- self.closeAllAct = QtGui.QAction("Close &All", self,
- statusTip="Close all the windows",
- triggered=self.mdiArea.closeAllSubWindows)
-
- self.urAct = QtGui.QAction("Update Rate", self, shortcut="F5",
- statusTip="Change Update Rate",
- triggered=self.updateRateShow)
-
- qks = QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_T);
- self.tileAct = QtGui.QAction("&Tile", self,
- statusTip="Tile the windows",
- triggered=self.mdiArea.tileSubWindows,
- shortcut=qks)
-
- qks = QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_C);
- self.cascadeAct = QtGui.QAction("&Cascade", self,
- statusTip="Cascade the windows", shortcut=qks,
- triggered=self.mdiArea.cascadeSubWindows)
-
- self.nextAct = QtGui.QAction("Ne&xt", self,
- shortcut=QtGui.QKeySequence.NextChild,
- statusTip="Move the focus to the next window",
- triggered=self.mdiArea.activateNextSubWindow)
-
- self.previousAct = QtGui.QAction("Pre&vious", self,
- shortcut=QtGui.QKeySequence.PreviousChild,
- statusTip="Move the focus to the previous window",
- triggered=self.mdiArea.activatePreviousSubWindow)
-
- self.separatorAct = QtGui.QAction(self)
- self.separatorAct.setSeparator(True)
-
- self.aboutAct = QtGui.QAction("&About", self,
- statusTip="Show the application's About box",
- triggered=self.about)
-
- self.aboutQtAct = QtGui.QAction("About &Qt", self,
- statusTip="Show the Qt library's About box",
- triggered=QtGui.qApp.aboutQt)
-
- def createMenus(self):
- self.fileMenu = self.menuBar().addMenu("&File")
- self.fileMenu.addAction(self.newConAct)
- self.fileMenu.addAction(self.newPlotAct)
- self.fileMenu.addAction(self.urAct)
- self.fileMenu.addSeparator()
- self.fileMenu.addAction(self.exitAct)
-
- self.windowMenu = self.menuBar().addMenu("&Window")
- self.updateWindowMenu()
- self.windowMenu.aboutToShow.connect(self.updateWindowMenu)
-
- self.menuBar().addSeparator()
-
- self.helpMenu = self.menuBar().addMenu("&Help")
- self.helpMenu.addAction(self.aboutAct)
- self.helpMenu.addAction(self.aboutQtAct)
-
- def updateRateShow(self):
- askrate = RateDialog(self.updateRate, self);
- if askrate.exec_():
- ur = float(str(askrate.delay.text()));
- self.setUpdateRate(ur);
- return;
- else:
- return;
-
- def createToolBars(self):
- self.fileToolBar = self.addToolBar("File")
- self.fileToolBar.addAction(self.newConAct)
- self.fileToolBar.addAction(self.newPlotAct)
- self.fileToolBar.addAction(self.urAct)
-
- self.fileToolBar = self.addToolBar("Window")
- self.fileToolBar.addAction(self.tileAct)
- self.fileToolBar.addAction(self.cascadeAct)
-
- def createStatusBar(self):
- self.statusBar().showMessage("Ready")
-
-
- def activeMdiChild(self):
- activeSubWindow = self.mdiArea.activeSubWindow()
- if activeSubWindow:
- return activeSubWindow.widget()
- return None
-
- def updateMenus(self):
- hasMdiChild = (self.activeMdiChild() is not None)
- self.closeAct.setEnabled(hasMdiChild)
- self.closeAllAct.setEnabled(hasMdiChild)
- self.tileAct.setEnabled(hasMdiChild)
- self.cascadeAct.setEnabled(hasMdiChild)
- self.nextAct.setEnabled(hasMdiChild)
- self.previousAct.setEnabled(hasMdiChild)
- self.separatorAct.setVisible(hasMdiChild)
-
- def updateWindowMenu(self):
- self.windowMenu.clear()
- self.windowMenu.addAction(self.closeAct)
- self.windowMenu.addAction(self.closeAllAct)
- self.windowMenu.addSeparator()
- self.windowMenu.addAction(self.tileAct)
- self.windowMenu.addAction(self.cascadeAct)
- self.windowMenu.addSeparator()
- self.windowMenu.addAction(self.nextAct)
- self.windowMenu.addAction(self.previousAct)
- self.windowMenu.addAction(self.separatorAct)
-
- def about(self):
- about_info = \
-'''Copyright 2012 Free Software Foundation, Inc.\n
-This program is part of GNU Radio.\n
-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 3, or (at your option) any later version.\n
-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.\n
-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., 51 Franklin Street, Boston, MA 02110-1301, USA.'''
-
- QtGui.QMessageBox.about(None, "gr-ctrlport-monitor", about_info)
-
-
-class ConInfoDialog(QtGui.QDialog):
- def __init__(self, parent=None):
- super(ConInfoDialog, self).__init__(parent)
-
- self.gridLayout = QtGui.QGridLayout(self)
-
-
- self.host = QtGui.QLineEdit(self);
- self.port = QtGui.QLineEdit(self);
- self.host.setText("localhost");
- self.port.setText("43243");
-
- self.buttonBox = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel)
-
- self.gridLayout.addWidget(self.host);
- self.gridLayout.addWidget(self.port);
- self.gridLayout.addWidget(self.buttonBox);
-
- self.buttonBox.accepted.connect(self.accept)
- self.buttonBox.rejected.connect(self.reject)
-
-
- def accept(self):
- self.done(1);
-
- def reject(self):
- self.done(0);
-
-
-class UpdaterWindow(QtGui.QDialog):
- def __init__(self, key, radio, parent):
- QtGui.QDialog.__init__(self, parent)
-
- self.key = key;
- self.radio = radio
-
- self.resize(300,200)
- self.layout = QtGui.QVBoxLayout()
-
- self.props = radio.properties([key])[key]
- info = str(self.props)
-
- self.infoLabel = QtGui.QLabel(info)
- self.layout.addWidget(self.infoLabel)
-
- # Test here to make sure that a 'set' function
- try:
- a = radio.set(radio.get([key]))
- has_set = True
- except Ice.UnknownException:
- has_set = False
-
- if(has_set is False):
- self.cancelButton = QtGui.QPushButton("Ok")
- self.cancelButton.connect(self.cancelButton, QtCore.SIGNAL('clicked()'), self.reject)
-
- self.buttonlayout = QtGui.QHBoxLayout()
- self.buttonlayout.addWidget(self.cancelButton)
- self.layout.addLayout(self.buttonlayout)
-
- else: # we have a set function
- self.textInput = QtGui.QLineEdit()
- self.layout.addWidget(self.textInput)
-
- self.applyButton = QtGui.QPushButton("Apply")
- self.setButton = QtGui.QPushButton("OK")
- self.cancelButton = QtGui.QPushButton("Cancel")
-
- rv = radio.get([key])
- self.textInput.setText(str(rv[key].value))
- self.sv = rv[key]
-
- self.applyButton.connect(self.applyButton, QtCore.SIGNAL('clicked()'), self._apply)
- self.setButton.connect(self.setButton, QtCore.SIGNAL('clicked()'), self._set)
- self.cancelButton.connect(self.cancelButton, QtCore.SIGNAL('clicked()'), self.reject)
-
- self.is_num = ((type(self.sv.value)==float) or (type(self.sv.value)==int))
- if(self.is_num):
- self.sliderlayout = QtGui.QHBoxLayout()
-
- self.slider = QtGui.QSlider(QtCore.Qt.Horizontal)
-
- self.sliderlayout.addWidget(QtGui.QLabel(str(self.props.min.value)))
- self.sliderlayout.addWidget(self.slider)
- self.sliderlayout.addWidget(QtGui.QLabel(str(self.props.max.value)))
-
- self.steps = 10000
- self.valspan = self.props.max.value - self.props.min.value
-
- self.slider.setRange(0, 10000)
- self._set_slider_value(self.sv.value)
-
- self.connect(self.slider, QtCore.SIGNAL("sliderReleased()"), self._slide)
-
- self.layout.addLayout(self.sliderlayout)
-
- self.buttonlayout = QtGui.QHBoxLayout()
- self.buttonlayout.addWidget(self.applyButton)
- self.buttonlayout.addWidget(self.setButton)
- self.buttonlayout.addWidget(self.cancelButton)
- self.layout.addLayout(self.buttonlayout)
-
- # set layout and go...
- self.setLayout(self.layout)
-
- def _set_slider_value(self, val):
- self.slider.setValue(self.steps*(val-self.props.min.value)/self.valspan)
-
- def _slide(self):
- val = (self.slider.value()*self.valspan + self.props.min.value)/float(self.steps)
- self.textInput.setText(str(val))
-
- def _apply(self):
- if(type(self.sv.value) == str):
- val = str(self.textInput.text())
- elif(type(self.sv.value) == int):
- val = int(round(float(self.textInput.text())))
- elif(type(self.sv.value) == float):
- val = float(self.textInput.text())
- else:
- sys.stderr.write("set type not supported! ({0})\n".format(type(self.sv.value)))
- sys.exit(-1)
-
- self.sv.value = val
- km = {}
- km[self.key] = self.sv
- self.radio.set(km)
- self._set_slider_value(self.sv.value)
-
- def _set(self):
- self._apply()
- self.done(0)
-
-
-class MForm(QtGui.QWidget):
- def update(self):
- try:
- st = time.time();
- knobs = self.radio.get([]);
- ft = time.time();
- latency = ft-st;
- self.parent.statusBar().showMessage("Current GNU Radio Control Port Query Latency: %f ms"%(latency*1000))
-
- except Exception, e:
- sys.stderr.write("ctrlport-monitor: radio.get threw exception ({0}).\n".format(e))
- if(type(self.parent) is MAINWindow):
- # Find window of connection
- remove = []
- for p in self.parent.mdiArea.subWindowList():
- if self.parent.conns[self.uid] == p.widget():
- remove.append(p)
-
- # Find any subplot windows of connection
- for p in self.parent.mdiArea.subWindowList():
- for plot in self.parent.plots[self.uid]:
- if plot.qwidget() == p.widget():
- remove.append(p)
-
- # Clean up local references to these
- self.parent.conns.remove(self.parent.conns[self.uid])
- self.parent.plots.remove(self.parent.plots[self.uid])
-
- # Remove subwindows for connection and plots
- for r in remove:
- self.parent.mdiArea.removeSubWindow(r)
-
- # Clean up self
- self.close()
- else:
- sys.exit(1)
- return
-
- tableitems = knobs.keys()
-
- #UPDATE TABLE:
- self.table.updateItems(knobs, self.knobprops)
-
- #UPDATE PLOTS
- self.parent.update(knobs, self.uid)
-
-
- def __init__(self, radio=None, port=None, uid=0, updateRate=2000, parent=None):
-
- super(MForm, self).__init__()
-
- if(radio == None or port == None):
- askinfo = ConInfoDialog(self);
- if askinfo.exec_():
- host = str(askinfo.host.text());
- port = str(askinfo.port.text());
- radio = parent.interface.getRadio(host, port)
- else:
- self.radio = None
- return
-
- self.uid = uid
- self.parent = parent
- self.horizontalLayout = QtGui.QVBoxLayout(self)
- self.gridLayout = QtGui.QGridLayout()
-
- self.radio = radio
- self.knobprops = self.radio.properties([])
- self.parent.knobprops.append(self.knobprops)
- self.resize(775,500)
- self.timer = QtCore.QTimer()
- self.constupdatediv = 0
- self.tableupdatediv = 0
- plotsize=250
-
- # make table
- self.table = GrDataPlotterValueTable(uid, self, 0, 0, 400, 200)
- sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
- self.table.treeWidget.setSizePolicy(sizePolicy)
- self.table.treeWidget.setEditTriggers(QtGui.QAbstractItemView.EditKeyPressed)
- self.table.treeWidget.setSortingEnabled(True)
- self.table.treeWidget.setDragEnabled(True)
-
- # add things to layouts
- self.horizontalLayout.addWidget(self.table.treeWidget)
-
- # set up timer
- self.connect(self.timer, QtCore.SIGNAL('timeout()'), self.update)
- self.updateRate = updateRate;
- self.timer.start(self.updateRate)
-
- # set up context menu ..
- self.table.treeWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
- self.table.treeWidget.customContextMenuRequested.connect(self.openMenu)
-
- # Set up double-click to launch default plotter
- self.connect(self.table.treeWidget,
- QtCore.SIGNAL('itemDoubleClicked(QTreeWidgetItem*, int)'),
- self.parent.newSub);
-
- # Allow drag/drop event from table item to plotter
- self.connect(self.table.treeWidget,
- QtCore.SIGNAL('itemPressed(QTreeWidgetItem*, int)'),
- self.parent.startDrag)
-
- def openMenu(self, pos):
- index = self.table.treeWidget.selectedIndexes()
- item = self.table.treeWidget.itemFromIndex(index[0])
- itemname = str(item.text(0))
- self.parent.propertiesMenu(itemname, self.radio, self.uid)
-
-
-class MyClient(IceRadioClient):
- def __init__(self):
- IceRadioClient.__init__(self, MAINWindow)
-
-sys.exit(MyClient().main(sys.argv))
diff --git a/gnuradio-core/src/python/gnuradio/ctrlport/gr-perf-monitor b/gnuradio-core/src/python/gnuradio/ctrlport/gr-perf-monitor
deleted file mode 100755
index f2c01691a1..0000000000
--- a/gnuradio-core/src/python/gnuradio/ctrlport/gr-perf-monitor
+++ /dev/null
@@ -1,591 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2012-2013 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from gnuradio import gr, ctrlport
-
-from PyQt4 import QtCore,Qt,Qwt5
-import PyQt4.QtGui as QtGui
-import sys, time, re, pprint
-import itertools
-import scipy
-
-import Ice
-from gnuradio.ctrlport.IceRadioClient import *
-from gnuradio.ctrlport.GrDataPlotter import *
-from gnuradio.ctrlport import GNURadio
-
-class MAINWindow(QtGui.QMainWindow):
- def minimumSizeHint(self):
- return QtGui.QSize(800,600)
-
- def __init__(self, radio, port, interface):
-
- super(MAINWindow, self).__init__()
- self.conns = []
- self.plots = []
- self.knobprops = []
- self.interface = interface
-
- self.mdiArea = QtGui.QMdiArea()
- self.mdiArea.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
- self.mdiArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
- self.setCentralWidget(self.mdiArea)
-
- self.mdiArea.subWindowActivated.connect(self.updateMenus)
- self.windowMapper = QtCore.QSignalMapper(self)
- self.windowMapper.mapped[QtGui.QWidget].connect(self.setActiveSubWindow)
-
- self.createActions()
- self.createMenus()
- self.createToolBars()
- self.createStatusBar()
- self.updateMenus()
-
- self.setWindowTitle("GNU Radio Performance Monitor")
- self.setUnifiedTitleAndToolBarOnMac(True)
-
- self.newCon(radio, port)
- icon = QtGui.QIcon(ctrlport.__path__[0] + "/icon.png" )
- self.setWindowIcon(icon)
-
- def newCon(self, radio=None, port=None):
- child = MForm(radio, port, len(self.conns), self)
- if(child.radio is not None):
- child.setWindowTitle(str(child.radio))
- horizbar = QtGui.QScrollArea()
- horizbar.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
- horizbar.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
- horizbar.setWidget(child)
- self.mdiArea.addSubWindow(horizbar)
- self.mdiArea.currentSubWindow().showMaximized()
-
- self.conns.append(child)
- self.plots.append([])
-
- def newUpdater(self, key, radio):
- updater = UpdaterWindow(key, radio, None)
- updater.setWindowTitle("Updater: " + key)
- updater.setModal(False)
- updater.exec_()
-
- def update(self, knobs, uid):
- #sys.stderr.write("KNOB KEYS: {0}\n".format(knobs.keys()))
- for plot in self.plots[uid]:
- data = knobs[plot.name()].value
- plot.update(data)
- plot.stop()
- plot.wait()
- plot.start()
-
- def setActiveSubWindow(self, window):
- if window:
- self.mdiArea.setActiveSubWindow(window)
-
-
- def createActions(self):
- self.newConAct = QtGui.QAction("&New Connection",
- self, shortcut=QtGui.QKeySequence.New,
- statusTip="Create a new file", triggered=self.newCon)
-
- self.exitAct = QtGui.QAction("E&xit", self, shortcut="Ctrl+Q",
- statusTip="Exit the application",
- triggered=QtGui.qApp.closeAllWindows)
-
- self.closeAct = QtGui.QAction("Cl&ose", self, shortcut="Ctrl+F4",
- statusTip="Close the active window",
- triggered=self.mdiArea.closeActiveSubWindow)
-
- self.closeAllAct = QtGui.QAction("Close &All", self,
- statusTip="Close all the windows",
- triggered=self.mdiArea.closeAllSubWindows)
-
-
- qks = QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_T);
- self.tileAct = QtGui.QAction("&Tile", self,
- statusTip="Tile the windows",
- triggered=self.mdiArea.tileSubWindows,
- shortcut=qks)
-
- qks = QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_C);
- self.cascadeAct = QtGui.QAction("&Cascade", self,
- statusTip="Cascade the windows", shortcut=qks,
- triggered=self.mdiArea.cascadeSubWindows)
-
- self.nextAct = QtGui.QAction("Ne&xt", self,
- shortcut=QtGui.QKeySequence.NextChild,
- statusTip="Move the focus to the next window",
- triggered=self.mdiArea.activateNextSubWindow)
-
- self.previousAct = QtGui.QAction("Pre&vious", self,
- shortcut=QtGui.QKeySequence.PreviousChild,
- statusTip="Move the focus to the previous window",
- triggered=self.mdiArea.activatePreviousSubWindow)
-
- self.separatorAct = QtGui.QAction(self)
- self.separatorAct.setSeparator(True)
-
- self.aboutAct = QtGui.QAction("&About", self,
- statusTip="Show the application's About box",
- triggered=self.about)
-
- self.aboutQtAct = QtGui.QAction("About &Qt", self,
- statusTip="Show the Qt library's About box",
- triggered=QtGui.qApp.aboutQt)
-
- def createMenus(self):
- self.fileMenu = self.menuBar().addMenu("&File")
- self.fileMenu.addAction(self.newConAct)
- self.fileMenu.addSeparator()
- self.fileMenu.addAction(self.exitAct)
-
- self.windowMenu = self.menuBar().addMenu("&Window")
- self.updateWindowMenu()
- self.windowMenu.aboutToShow.connect(self.updateWindowMenu)
-
- self.menuBar().addSeparator()
-
- self.helpMenu = self.menuBar().addMenu("&Help")
- self.helpMenu.addAction(self.aboutAct)
- self.helpMenu.addAction(self.aboutQtAct)
-
- def createToolBars(self):
- self.fileToolBar = self.addToolBar("File")
- self.fileToolBar.addAction(self.newConAct)
-
- self.fileToolBar = self.addToolBar("Window")
- self.fileToolBar.addAction(self.tileAct)
- self.fileToolBar.addAction(self.cascadeAct)
-
- def createStatusBar(self):
- self.statusBar().showMessage("Ready")
-
-
- def activeMdiChild(self):
- activeSubWindow = self.mdiArea.activeSubWindow()
- if activeSubWindow:
- return activeSubWindow.widget()
- return None
-
- def updateMenus(self):
- hasMdiChild = (self.activeMdiChild() is not None)
- self.closeAct.setEnabled(hasMdiChild)
- self.closeAllAct.setEnabled(hasMdiChild)
- self.tileAct.setEnabled(hasMdiChild)
- self.cascadeAct.setEnabled(hasMdiChild)
- self.nextAct.setEnabled(hasMdiChild)
- self.previousAct.setEnabled(hasMdiChild)
- self.separatorAct.setVisible(hasMdiChild)
-
- def updateWindowMenu(self):
- self.windowMenu.clear()
- self.windowMenu.addAction(self.closeAct)
- self.windowMenu.addAction(self.closeAllAct)
- self.windowMenu.addSeparator()
- self.windowMenu.addAction(self.tileAct)
- self.windowMenu.addAction(self.cascadeAct)
- self.windowMenu.addSeparator()
- self.windowMenu.addAction(self.nextAct)
- self.windowMenu.addAction(self.previousAct)
- self.windowMenu.addAction(self.separatorAct)
-
- def about(self):
- about_info = \
-'''Copyright 2012 Free Software Foundation, Inc.\n
-This program is part of GNU Radio.\n
-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 3, or (at your option) any later version.\n
-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.\n
-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., 51 Franklin Street, Boston, MA 02110-1301, USA.'''
-
- QtGui.QMessageBox.about(None, "gr-ctrlport-monitor", about_info)
-
-
-class ConInfoDialog(QtGui.QDialog):
- def __init__(self, parent=None):
- super(ConInfoDialog, self).__init__(parent)
-
- self.gridLayout = QtGui.QGridLayout(self)
-
-
- self.host = QtGui.QLineEdit(self);
- self.port = QtGui.QLineEdit(self);
- self.host.setText("localhost");
- self.port.setText("43243");
-
- self.buttonBox = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok |
- QtGui.QDialogButtonBox.Cancel)
-
- self.gridLayout.addWidget(self.host);
- self.gridLayout.addWidget(self.port);
- self.gridLayout.addWidget(self.buttonBox);
-
- self.buttonBox.accepted.connect(self.accept)
- self.buttonBox.rejected.connect(self.reject)
-
-
- def accept(self):
- self.done(1);
-
- def reject(self):
- self.done(0);
-
-
-class UpdaterWindow(QtGui.QDialog):
- def __init__(self, key, radio, parent):
- QtGui.QDialog.__init__(self, parent)
-
- self.key = key;
- self.radio = radio
-
- self.resize(300,200)
- self.layout = QtGui.QVBoxLayout()
-
- self.props = radio.properties([key])[key]
- info = str(self.props)
-
- self.infoLabel = QtGui.QLabel(info)
- self.layout.addWidget(self.infoLabel)
-
- self.cancelButton = QtGui.QPushButton("Ok")
- self.cancelButton.connect(self.cancelButton, QtCore.SIGNAL('clicked()'), self.reject)
-
- self.buttonlayout = QtGui.QHBoxLayout()
- self.buttonlayout.addWidget(self.cancelButton)
- self.layout.addLayout(self.buttonlayout)
-
- # set layout and go...
- self.setLayout(self.layout)
-
- def _set_slider_value(self, val):
- self.slider.setValue(self.steps*(val-self.props.min.value)/self.valspan)
-
- def _slide(self):
- val = (self.slider.value()*self.valspan + self.props.min.value)/float(self.steps)
- self.textInput.setText(str(val))
-
- def _apply(self):
- if(type(self.sv.value) == str):
- val = str(self.textInput.text())
- elif(type(self.sv.value) == int):
- val = int(round(float(self.textInput.text())))
- elif(type(self.sv.value) == float):
- val = float(self.textInput.text())
- else:
- sys.stderr.write("set type not supported! ({0})\n".format(type(self.sv.value)))
- sys.exit(-1)
-
- self.sv.value = val
- km = {}
- km[self.key] = self.sv
- self.radio.set(km)
- self._set_slider_value(self.sv.value)
-
- def _set(self):
- self._apply()
- self.done(0)
-
-
-def build_edge_graph(sources, sinks, edges):
- '''
- Starting from the sources, walks through all of the edges to find
- the next connected block. The output is stored in 'allblocks'
- where each row starts with a source and follows one path down
- until it terminates in either a sink or as an input to a block
- that is part of another chain.
- '''
- def find_edge(src, sinks, edges, row, col):
- #print "\n\nAll blocks: "
- #printer.pprint(allblocks)
- #print "\nLooking for: ", src
-
- src0 = src.split(":")[0]
- if(src0 in sinks):
- if(len(allblocks) <= row):
- allblocks.append(col*[""])
- allblocks[row].append(src)
- return row+1
-
- for edge in edges:
- if(re.match(src0, edge)):
- s = edge.split("->")[0]
- b = edge.split("->")[1]
- if(len(allblocks) <= row):
- allblocks.append(col*[""])
- allblocks[row].append(s)
- #print "Source: {0} Sink: {1}".format(s, b)
- row = find_edge(b, sinks, edges, row, col+1)
- return row
-
- # Recursively get all edges as a matrix of source->sink
- n = 0
- allblocks = []
- for src in sources:
- n = find_edge(src, sinks, edges, n, 0)
-
- # Sort by longest list
- allblocks = sorted(allblocks, key=len)
- allblocks.reverse()
-
- # Make all rows same length by padding '' in front of sort rows
- maxrowlen = len(allblocks[0])
- for i,a in enumerate(allblocks):
- rowlen = len(a)
- allblocks[i] = (maxrowlen-rowlen)*[''] + a
-
- # Dedup rows
- allblocks = sorted(allblocks)
- allblocks = list(k for k,_ in itertools.groupby(allblocks))
- allblocks.reverse()
-
- return allblocks
-
-
-class MForm(QtGui.QWidget):
- def update(self):
- try:
- st = time.time()
- knobs = self.radio.get([b[0] for b in self.block_dict])
-
- ft = time.time()
- latency = ft-st
- self.parent.statusBar().showMessage("Current GNU Radio Control Port Query Latency: %f ms"%\
- (latency*1000))
-
- except Exception, e:
- sys.stderr.write("ctrlport-monitor: radio.get threw exception ({0}).\n".format(e))
- if(type(self.parent) is MAINWindow):
- # Find window of connection
- remove = []
- for p in self.parent.mdiArea.subWindowList():
- if self.parent.conns[self.uid] == p.widget():
- remove.append(p)
-
- # Find any subplot windows of connection
- for p in self.parent.mdiArea.subWindowList():
- for plot in self.parent.plots[self.uid]:
- if plot.qwidget() == p.widget():
- remove.append(p)
-
- # Clean up local references to these
- self.parent.conns.remove(self.parent.conns[self.uid])
- self.parent.plots.remove(self.parent.plots[self.uid])
-
- # Remove subwindows for connection and plots
- for r in remove:
- self.parent.mdiArea.removeSubWindow(r)
-
- # Clean up self
- self.close()
- else:
- sys.exit(1)
- return
-
- #UPDATE TABLE:
- self.updateItems(knobs)
-
- #UPDATE PLOTS
- self.parent.update(knobs, self.uid)
-
- def updateItems(self, knobs):
- for b in self.block_dict:
- if(knobs[b[0]].ice_id.im_class == GNURadio.KnobVecF):
- b[1].setText("{0:.4f}".format(knobs[b[0]].value[b[2]]))
- else:
- b[1].setText("{0:.4f}".format(knobs[b[0]].value))
-
- def __init__(self, radio=None, port=None, uid=0, parent=None):
-
- super(MForm, self).__init__()
-
- if(radio == None or port == None):
- askinfo = ConInfoDialog(self);
- if askinfo.exec_():
- host = str(askinfo.host.text());
- port = str(askinfo.port.text());
- radio = parent.interface.getRadio(host, port)
- else:
- self.radio = None
- return
-
- self.uid = uid
- self.parent = parent
- self.layout = QtGui.QGridLayout(self)
- self.layout.setSizeConstraint(QtGui.QLayout.SetFixedSize)
-
- self.radio = radio
- self.knobprops = self.radio.properties([])
- self.parent.knobprops.append(self.knobprops)
- self.resize(775,500)
- self.timer = QtCore.QTimer()
- self.constupdatediv = 0
- self.tableupdatediv = 0
- plotsize=250
-
-
- # Set up the graph of blocks
- input_name = lambda x: x+"::avg input % full"
- output_name = lambda x: x+"::avg output % full"
- wtime_name = lambda x: x+"::avg work time"
- nout_name = lambda x: x+"::avg noutput_items"
- nprod_name = lambda x: x+"::avg nproduced"
-
- tmplist = []
- knobs = self.radio.get([])
- edgelist = None
- for k in knobs:
- propname = k.split("::")
- blockname = propname[0]
- keyname = propname[1]
- if(keyname == "edge list"):
- edgelist = knobs[k].value
- elif(blockname not in tmplist):
- # only take gr_blocks (no hier_block2)
- if(knobs.has_key(input_name(blockname))):
- tmplist.append(blockname)
-
- if not edgelist:
- sys.stderr.write("Could not find list of edges from flowgraph. " + \
- "Make sure the option 'edges_list' is enabled " + \
- "in the ControlPort configuration.\n\n")
- sys.exit(1)
-
- edges = edgelist.split("\n")[0:-1]
- producers = []
- consumers = []
- for e in edges:
- _e = e.split("->")
- producers.append(_e[0])
- consumers.append(_e[1])
-
- # Get producers and consumers as sets while ignoring the
- # ports.
- prods = set(map(lambda x: x.split(":")[0], producers))
- cons = set(map(lambda x: x.split(":")[0], consumers))
-
- # Split out all blocks, sources, and sinks based on how they
- # appear as consumers and/or producers.
- blocks = prods.intersection(cons)
- sources = prods.difference(blocks)
- sinks = cons.difference(blocks)
-
- nblocks = len(prods) + len(cons)
-
- allblocks = build_edge_graph(sources, sinks, edges)
- nrows = len(allblocks)
- ncols = len(allblocks[0])
-
- col_width = 120
-
- self.block_dict = []
-
- for row, blockrow in enumerate(allblocks):
- for col, block in enumerate(blockrow):
- if(block == ''):
- continue
-
- bgroup = QtGui.QGroupBox(block)
- playout = QtGui.QFormLayout()
- bgroup.setLayout(playout)
- self.layout.addWidget(bgroup, row, 2*col)
-
- blockname = block.split(":")[0]
-
- name = wtime_name(blockname)
- wtime = knobs[name].value
- newtime = QtGui.QLineEdit()
- newtime.setMinimumWidth(col_width)
- newtime.setText("{0:.4f}".format(wtime))
- self.block_dict.append((name, newtime))
-
- name = nout_name(blockname)
- nout = knobs[name].value
- newnout = QtGui.QLineEdit()
- newnout.setText("{0:.4f}".format(nout))
- newnout.setMinimumWidth(col_width)
- self.block_dict.append((name, newnout))
-
- name = nprod_name(blockname)
- nprod = knobs[name].value
- newnprod = QtGui.QLineEdit()
- newnprod.setMinimumWidth(col_width)
- newnprod.setText("{0:.4f}".format(nprod))
- self.block_dict.append((name, newnprod))
-
- playout.addRow("Work time", newtime)
- playout.addRow("noutput_items", newnout)
- playout.addRow("nproduced", newnprod)
-
- if blockname in blocks or blockname in sources:
- # Add a buffer between blocks
- buffgroup = QtGui.QGroupBox("Buffer")
- bufflayout = QtGui.QFormLayout()
- buffgroup.setLayout(bufflayout)
- self.layout.addWidget(buffgroup, row, 2*col+1)
-
- i = int(block.split(":")[1])
- name = output_name(blockname)
- obuff = knobs[name].value
- for i,o in enumerate(obuff):
- newobuff = QtGui.QLineEdit()
- newobuff.setMinimumWidth(col_width)
- newobuff.setText("{0:.4f}".format(o))
- self.block_dict.append((name, newobuff, i))
- bufflayout.addRow("Out Buffer {0}".format(i),
- newobuff)
-
- if blockname in blocks or blockname in sinks:
- item = self.layout.itemAtPosition(row, 2*col-1)
- if(item):
- buffgroup = item.widget()
- bufflayout = buffgroup.layout()
- else:
- buffgroup = QtGui.QGroupBox("Buffer")
- bufflayout = QtGui.QFormLayout()
- buffgroup.setLayout(bufflayout)
- self.layout.addWidget(buffgroup, row, 2*col-1)
-
- i = int(block.split(":")[1])
- name = input_name(blockname)
- ibuff = knobs[name].value[i]
- newibuff = QtGui.QLineEdit()
- newibuff.setMinimumWidth(col_width)
- newibuff.setText("{0:.4f}".format(ibuff))
- self.block_dict.append((name, newibuff, i))
- bufflayout.addRow("In Buffer {0}".format(i),
- newibuff)
-
- # set up timer
- self.timer = QtCore.QTimer()
- self.connect(self.timer, QtCore.SIGNAL('timeout()'), self.update)
- self.timer.start(1000)
-
- def openMenu(self, pos):
- index = self.table.treeWidget.selectedIndexes()
- item = self.table.treeWidget.itemFromIndex(index[0])
- itemname = str(item.text(0))
- self.parent.propertiesMenu(itemname, self.radio, self.uid)
-
-
-class MyClient(IceRadioClient):
- def __init__(self):
- IceRadioClient.__init__(self, MAINWindow)
-
-sys.exit(MyClient().main(sys.argv))
diff --git a/gnuradio-core/src/python/gnuradio/ctrlport/gr-perf-monitorx b/gnuradio-core/src/python/gnuradio/ctrlport/gr-perf-monitorx
deleted file mode 100755
index a65b0406e4..0000000000
--- a/gnuradio-core/src/python/gnuradio/ctrlport/gr-perf-monitorx
+++ /dev/null
@@ -1,727 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2012-2013 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-import random,math,operator
-import networkx as nx;
-import matplotlib.pyplot as plt
-
-from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
-from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar
-from matplotlib.figure import Figure
-
-from gnuradio import gr, ctrlport
-
-from PyQt4 import QtCore,Qt,Qwt5
-import PyQt4.QtGui as QtGui
-import sys, time, re, pprint
-import itertools
-import scipy
-from scipy import spatial
-
-import Ice
-from gnuradio.ctrlport.IceRadioClient import *
-from gnuradio.ctrlport.GrDataPlotter import *
-from gnuradio.ctrlport import GNURadio
-
-class MAINWindow(QtGui.QMainWindow):
- def minimumSizeHint(self):
- return QtGui.QSize(800,600)
-
- def __init__(self, radio, port, interface):
-
- super(MAINWindow, self).__init__()
- self.conns = []
- self.plots = []
- self.knobprops = []
- self.interface = interface
-
- self.mdiArea = QtGui.QMdiArea()
- self.mdiArea.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
- self.mdiArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
- self.setCentralWidget(self.mdiArea)
-
- self.mdiArea.subWindowActivated.connect(self.updateMenus)
- self.windowMapper = QtCore.QSignalMapper(self)
- self.windowMapper.mapped[QtGui.QWidget].connect(self.setActiveSubWindow)
-
- self.createActions()
- self.createMenus()
- self.createToolBars()
- self.createStatusBar()
- self.updateMenus()
-
- self.setWindowTitle("GNU Radio Performance Monitor")
- self.setUnifiedTitleAndToolBarOnMac(True)
-
- self.newCon(radio, port)
- icon = QtGui.QIcon(ctrlport.__path__[0] + "/icon.png" )
- self.setWindowIcon(icon)
-
-
- def newSubWindow(self, window, title):
- child = window;
- child.setWindowTitle(title)
- self.mdiArea.addSubWindow(child)
- self.conns.append(child)
- child.show();
- self.mdiArea.currentSubWindow().showMaximized()
-
-
- def newCon(self, radio=None, port=None):
- child = MForm(radio, port, len(self.conns), self)
- if(child.radio is not None):
- child.setWindowTitle(str(child.radio))
-# horizbar = QtGui.QScrollArea()
-# horizbar.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
-# horizbar.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
-# horizbar.setWidget(child)
-# self.mdiArea.addSubWindow(horizbar)
- self.mdiArea.addSubWindow(child)
- self.mdiArea.currentSubWindow().showMaximized()
-
- self.conns.append(child)
- self.plots.append([])
-
- def update(self, knobs, uid):
- #sys.stderr.write("KNOB KEYS: {0}\n".format(knobs.keys()))
- for plot in self.plots[uid]:
- data = knobs[plot.name()].value
- plot.update(data)
- plot.stop()
- plot.wait()
- plot.start()
-
- def setActiveSubWindow(self, window):
- if window:
- self.mdiArea.setActiveSubWindow(window)
-
-
- def createActions(self):
- self.newConAct = QtGui.QAction("&New Connection",
- self, shortcut=QtGui.QKeySequence.New,
- statusTip="Create a new file", triggered=self.newCon)
-
- self.exitAct = QtGui.QAction("E&xit", self, shortcut="Ctrl+Q",
- statusTip="Exit the application",
- triggered=QtGui.qApp.closeAllWindows)
-
- self.closeAct = QtGui.QAction("Cl&ose", self, shortcut="Ctrl+F4",
- statusTip="Close the active window",
- triggered=self.mdiArea.closeActiveSubWindow)
-
- self.closeAllAct = QtGui.QAction("Close &All", self,
- statusTip="Close all the windows",
- triggered=self.mdiArea.closeAllSubWindows)
-
-
- qks = QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_T);
- self.tileAct = QtGui.QAction("&Tile", self,
- statusTip="Tile the windows",
- triggered=self.mdiArea.tileSubWindows,
- shortcut=qks)
-
- qks = QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_C);
- self.cascadeAct = QtGui.QAction("&Cascade", self,
- statusTip="Cascade the windows", shortcut=qks,
- triggered=self.mdiArea.cascadeSubWindows)
-
- self.nextAct = QtGui.QAction("Ne&xt", self,
- shortcut=QtGui.QKeySequence.NextChild,
- statusTip="Move the focus to the next window",
- triggered=self.mdiArea.activateNextSubWindow)
-
- self.previousAct = QtGui.QAction("Pre&vious", self,
- shortcut=QtGui.QKeySequence.PreviousChild,
- statusTip="Move the focus to the previous window",
- triggered=self.mdiArea.activatePreviousSubWindow)
-
- self.separatorAct = QtGui.QAction(self)
- self.separatorAct.setSeparator(True)
-
- self.aboutAct = QtGui.QAction("&About", self,
- statusTip="Show the application's About box",
- triggered=self.about)
-
- self.aboutQtAct = QtGui.QAction("About &Qt", self,
- statusTip="Show the Qt library's About box",
- triggered=QtGui.qApp.aboutQt)
-
- def createMenus(self):
- self.fileMenu = self.menuBar().addMenu("&File")
- self.fileMenu.addAction(self.newConAct)
- self.fileMenu.addSeparator()
- self.fileMenu.addAction(self.exitAct)
-
- self.windowMenu = self.menuBar().addMenu("&Window")
- self.updateWindowMenu()
- self.windowMenu.aboutToShow.connect(self.updateWindowMenu)
-
- self.menuBar().addSeparator()
-
- self.helpMenu = self.menuBar().addMenu("&Help")
- self.helpMenu.addAction(self.aboutAct)
- self.helpMenu.addAction(self.aboutQtAct)
-
- def createToolBars(self):
- self.fileToolBar = self.addToolBar("File")
- self.fileToolBar.addAction(self.newConAct)
-
- self.fileToolBar = self.addToolBar("Window")
- self.fileToolBar.addAction(self.tileAct)
- self.fileToolBar.addAction(self.cascadeAct)
-
- def createStatusBar(self):
- self.statusBar().showMessage("Ready")
-
-
- def activeMdiChild(self):
- activeSubWindow = self.mdiArea.activeSubWindow()
- if activeSubWindow:
- return activeSubWindow.widget()
- return None
-
- def updateMenus(self):
- hasMdiChild = (self.activeMdiChild() is not None)
- self.closeAct.setEnabled(hasMdiChild)
- self.closeAllAct.setEnabled(hasMdiChild)
- self.tileAct.setEnabled(hasMdiChild)
- self.cascadeAct.setEnabled(hasMdiChild)
- self.nextAct.setEnabled(hasMdiChild)
- self.previousAct.setEnabled(hasMdiChild)
- self.separatorAct.setVisible(hasMdiChild)
-
- def updateWindowMenu(self):
- self.windowMenu.clear()
- self.windowMenu.addAction(self.closeAct)
- self.windowMenu.addAction(self.closeAllAct)
- self.windowMenu.addSeparator()
- self.windowMenu.addAction(self.tileAct)
- self.windowMenu.addAction(self.cascadeAct)
- self.windowMenu.addSeparator()
- self.windowMenu.addAction(self.nextAct)
- self.windowMenu.addAction(self.previousAct)
- self.windowMenu.addAction(self.separatorAct)
-
- def about(self):
- about_info = \
-'''Copyright 2012 Free Software Foundation, Inc.\n
-This program is part of GNU Radio.\n
-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 3, or (at your option) any later version.\n
-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.\n
-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., 51 Franklin Street, Boston, MA 02110-1301, USA.'''
-
- QtGui.QMessageBox.about(None, "gr-ctrlport-monitor", about_info)
-
-
-class ConInfoDialog(QtGui.QDialog):
- def __init__(self, parent=None):
- super(ConInfoDialog, self).__init__(parent)
-
- self.gridLayout = QtGui.QGridLayout(self)
-
-
- self.host = QtGui.QLineEdit(self);
- self.port = QtGui.QLineEdit(self);
- self.host.setText("localhost");
- self.port.setText("43243");
-
- self.buttonBox = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok |
- QtGui.QDialogButtonBox.Cancel)
-
- self.gridLayout.addWidget(self.host);
- self.gridLayout.addWidget(self.port);
- self.gridLayout.addWidget(self.buttonBox);
-
- self.buttonBox.accepted.connect(self.accept)
- self.buttonBox.rejected.connect(self.reject)
-
-
- def accept(self):
- self.done(1);
-
- def reject(self):
- self.done(0);
-
-
-class DataTable(QtGui.QWidget):
- def update(self):
- print "update"
-
- def __init__(self, radio, G):
- QtGui.QWidget.__init__( self)
-
- self.layout = QtGui.QVBoxLayout(self);
- self.hlayout = QtGui.QHBoxLayout();
- self.layout.addLayout(self.hlayout);
-
- self.G = G;
- self.radio = radio;
-
- self._keymap = None
-
- # Create a combobox to set the type of statistic we want.
- self._statistic = "Instantaneous"
- self._statistics_table = {"Instantaneous": "",
- "Average": "avg ",
- "Variance": "var "}
- self.stattype = QtGui.QComboBox()
- self.stattype.addItem("Instantaneous")
- self.stattype.addItem("Average")
- self.stattype.addItem("Variance")
- self.stattype.setMaximumWidth(200)
- self.hlayout.addWidget(self.stattype);
- self.stattype.currentIndexChanged.connect(self.stat_changed)
-
- # Create a checkbox to toggle sorting of graphs
- self._sort = False
- self.checksort = QtGui.QCheckBox("Sort")
- self.checksort.setCheckState(self._sort)
- self.hlayout.addWidget(self.checksort);
- self.checksort.stateChanged.connect(self.checksort_changed)
-
- # set up table
- 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.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.set_autoscale_on(True)
- self.canvas = FigureCanvas(self.f)
-
- # set up tabs
- self.tabber = QtGui.QTabWidget();
- self.layout.addWidget(self.tabber);
- self.tabber.addTab(self.perfTable,"Table View");
- self.tabber.addTab(self.canvas, "Graph View");
-
- # set up timer
- self.timer = QtCore.QTimer()
- self.connect(self.timer, QtCore.SIGNAL('timeout()'), self.update)
- self.timer.start(500)
-
- for i in range(0,len(nodes)):
- self.perfTable.setItem(
- i,0,
- Qt.QTableWidgetItem(nodes[i][0]))
-
- def table_update(self,data):
- for k in data.keys():
- weight = data[k]
- existing = self.perfTable.findItems(str(k),QtCore.Qt.MatchFixedString)
- if(len(existing) == 0):
- i = self.perfTable.rowCount();
- self.perfTable.setRowCount( i+1)
- self.perfTable.setItem( i,0, Qt.QTableWidgetItem(str(k)))
- self.perfTable.setItem( i,1, Qt.QTableWidgetItem(str(weight)))
- else:
- self.perfTable.setItem( self.perfTable.row(existing[0]),1, Qt.QTableWidgetItem(str(weight)))
-
- def stat_changed(self, index):
- self._statistic = str(self.stattype.currentText())
-
- def checksort_changed(self, state):
- self._sort = state > 0
-
-class DataTableBuffers(DataTable):
- def __init__(self, radio, G):
- DataTable.__init__(self,radio,G)
- 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]),
- nodes);
- buf_knobs = self.radio.get(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())))
-
- blockport_fullness = {}
- for blk in buffer_fullness:
- for port in range(0,len(buffer_fullness[blk])):
- blockport_fullness["%s:%d"%(blk,port)] = buffer_fullness[blk][port];
-
- 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])
- else:
- sorted_fullness = blockport_fullness.items()
-
- self.sp.clear();
- plt.figure(self.f.number)
- plt.subplot(111);
- 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();
-
-class DataTableRuntimes(DataTable):
- def __init__(self, radio, G):
- DataTable.__init__(self,radio,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]),
- nodes);
- wrk_knobs = self.radio.get(kl)
-
- # strip values out of ctrlport response
- total_work = sum(map(lambda x: x.value, wrk_knobs.values()))
- work_times = dict(zip(
- map(lambda x: x.split("::")[0], wrk_knobs.keys()),
- map(lambda x: x.value/total_work, wrk_knobs.values())))
-
- # update table view
- 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])
- 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" )
-
- self.canvas.draw();
- self.canvas.show();
-
-class MForm(QtGui.QWidget):
- def update(self):
- try:
-
- nodes = self.G.nodes();
-
- # get current buffer depths of all output buffers
- kl = map(lambda x: "%s::%soutput %% full" % \
- (x, self._statistics_table[self._statistic]),
- nodes);
-
- st = time.time()
- buf_knobs = self.radio.get(kl)
- td1 = time.time() - st;
-
- # strip values out of ctrlport response
- buf_vals = dict(zip(
- map(lambda x: x.split("::")[0], buf_knobs.keys()),
- map(lambda x: x.value, buf_knobs.values())))
-
- # get work time for all blocks
- kl = map(lambda x: "%s::%swork time" % \
- (x, self._statistics_table[self._statistic]),
- nodes);
- st = time.time()
- wrk_knobs = self.radio.get(kl)
- td2 = time.time() - st;
-
- # strip values out of ctrlport response
- total_work = sum(map(lambda x: x.value, wrk_knobs.values()))
- work_times = dict(zip(
- map(lambda x: x.split("::")[0], wrk_knobs.keys()),
- map(lambda x: x.value/total_work, wrk_knobs.values())))
-
- for n in nodes:
- # ne is the list of edges away from this node!
- ne = self.G.edges([n],True);
- for e in ne: # iterate over edges from this block
- # get the right output buffer/port weight for each edge
- sourceport = e[2]["sourceport"];
- newweight = buf_vals[n][sourceport]
- e[2]["weight"] = newweight;
-
- # set updated weights
- self.node_weights = map(lambda x: 20+2000*work_times[x], nodes);
- self.edge_weights = map(lambda x: 100.0*x[2]["weight"], self.G.edges(data=True));
-
- # draw graph updates
- self.updateGraph();
-
- latency = td1 + td2;
- self.parent.statusBar().showMessage("Current GNU Radio Control Port Query Latency: %f ms"%\
- (latency*1000))
-
- except Exception, e:
- sys.stderr.write("ctrlport-monitor: radio.get threw exception ({0}).\n".format(e))
- if(type(self.parent) is MAINWindow):
- # Find window of connection
- remove = []
- for p in self.parent.mdiArea.subWindowList():
- if self.parent.conns[self.uid] == p.widget():
- remove.append(p)
-
- # Remove subwindows for connection and plots
- for r in remove:
- self.parent.mdiArea.removeSubWindow(r)
-
- # Clean up self
- self.close()
- else:
- sys.exit(1)
- return
-
- def rtt(self):
- self.parent.newSubWindow( DataTableRuntimes(self.radio, self.G), "Runtime Table" );
-
- def bpt(self):
- self.parent.newSubWindow( DataTableBuffers(self.radio, self.G), "Buffers Table" );
-
- def stat_changed(self, index):
- self._statistic = str(self.stattype.currentText())
-
- def __init__(self, radio=None, port=None, uid=0, parent=None):
-
- super(MForm, self).__init__()
-
- if(radio == None or port == None):
- askinfo = ConInfoDialog(self);
- if askinfo.exec_():
- host = str(askinfo.host.text());
- port = str(askinfo.port.text());
- radio = parent.interface.getRadio(host, port)
- else:
- self.radio = None
- return
-
-
- self.uid = uid
- self.parent = parent
-
- self.layoutTop = QtGui.QVBoxLayout(self)
- self.ctlBox = QtGui.QHBoxLayout();
- self.layout = QtGui.QHBoxLayout()
-
- self.layoutTop.addLayout(self.ctlBox);
- self.layoutTop.addLayout(self.layout);
-
- self.rttAct = QtGui.QAction("Runtime Table",
- self, statusTip="Runtime Table", triggered=self.rtt)
- self.rttBut = Qt.QToolButton()
- self.rttBut.setDefaultAction(self.rttAct);
- self.ctlBox.addWidget(self.rttBut);
-
- self.bptAct = QtGui.QAction("Buffer Table",
- self, statusTip="Buffer Table", triggered=self.bpt)
- self.bptBut = Qt.QToolButton()
- self.bptBut.setDefaultAction(self.bptAct);
- self.ctlBox.addWidget(self.bptBut);
-
- self._statistic = "Instantaneous"
- self._statistics_table = {"Instantaneous": "",
- "Average": "avg ",
- "Variance": "var "}
- self.stattype = QtGui.QComboBox()
- self.stattype.addItem("Instantaneous")
- self.stattype.addItem("Average")
- self.stattype.addItem("Variance")
- self.stattype.setMaximumWidth(200)
- self.ctlBox.addWidget(self.stattype);
- self.stattype.currentIndexChanged.connect(self.stat_changed)
-
-# self.setLayout(self.layout);
-
- self.radio = radio
- self.knobprops = self.radio.properties([])
- self.parent.knobprops.append(self.knobprops)
-
- self.timer = QtCore.QTimer()
- self.constupdatediv = 0
- self.tableupdatediv = 0
- plotsize=250
-
-
- # Set up the graph of blocks
- input_name = lambda x: x+"::avg input % full"
- output_name = lambda x: x+"::avg output % full"
- wtime_name = lambda x: x+"::avg work time"
- nout_name = lambda x: x+"::avg noutput_items"
- nprod_name = lambda x: x+"::avg nproduced"
-
- tmplist = []
- knobs = self.radio.get([])
- edgelist = None
- for k in knobs:
- propname = k.split("::")
- blockname = propname[0]
- keyname = propname[1]
- if(keyname == "edge list"):
- edgelist = knobs[k].value
- elif(blockname not in tmplist):
- # only take gr_blocks (no hier_block2)
- if(knobs.has_key(input_name(blockname))):
- tmplist.append(blockname)
-
- if not edgelist:
- sys.stderr.write("Could not find list of edges from flowgraph. " + \
- "Make sure the option 'edges_list' is enabled " + \
- "in the ControlPort configuration.\n\n")
- sys.exit(1)
-
- edges = edgelist.split("\n")[0:-1]
- edgepairs = [];
- for e in edges:
- _e = e.split("->")
- edgepairs.append( (_e[0].split(":")[0], _e[1].split(":")[0],
- {"sourceport":int(_e[0].split(":")[1])}) );
-
- self.G = nx.MultiDiGraph();
- self.G.add_edges_from(edgepairs);
-
- n_edges = self.G.edges(data=True);
- for e in n_edges:
- e[2]["weight"] = 5+random.random()*10;
-
- self.G.clear();
- self.G.add_edges_from(n_edges);
-
-
- 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.set_autoscale_on(True)
-
- self.canvas = FigureCanvas(self.f)
- self.layout.addWidget(self.canvas);
-
- self.pos = nx.graphviz_layout(self.G);
- #self.pos = nx.pygraphviz_layout(self.G);
- #self.pos = nx.spectral_layout(self.G);
- #self.pos = nx.circular_layout(self.G);
- #self.pos = nx.shell_layout(self.G);
- #self.pos = nx.spring_layout(self.G);
-
- # generate weights and plot
- self.update();
-
- # set up timer
- self.timer = QtCore.QTimer()
- self.connect(self.timer, QtCore.SIGNAL('timeout()'), self.update)
- self.timer.start(1000)
-
- # Set up mouse callback functions to move blocks around.
- self._grabbed = False
- self._current_block = ''
- self.f.canvas.mpl_connect('button_press_event',
- self.button_press)
- self.f.canvas.mpl_connect('motion_notify_event',
- self.mouse_move)
- self.f.canvas.mpl_connect('button_release_event',
- self.button_release)
-
- def button_press(self, event):
- x, y = event.xdata, event.ydata
- thrsh = 100
-
- if(x is not None and y is not None):
- nearby = map(lambda z: spatial.distance.euclidean((x,y), z), self.pos.values())
- i = nearby.index(min(nearby))
- if(abs(self.pos.values()[i][0] - x) < thrsh and
- abs(self.pos.values()[i][1]-y) < thrsh):
- self._current_block = self.pos.keys()[i]
- #print "MOVING BLOCK: ", self._current_block
- #print "CUR POS: ", self.pos.values()[i]
- self._grabbed = True
-
- def mouse_move(self, event):
- if self._grabbed:
- x, y = event.xdata, event.ydata
- if(x is not None and y is not None):
- #print "NEW POS: ", (x,y)
- self.pos[self._current_block] = (x,y)
- self.updateGraph();
-
- def button_release(self, event):
- self._grabbed = False
-
-
- def openMenu(self, pos):
- index = self.table.treeWidget.selectedIndexes()
- item = self.table.treeWidget.itemFromIndex(index[0])
- itemname = str(item.text(0))
- self.parent.propertiesMenu(itemname, self.radio, self.uid)
-
- def updateGraph(self):
-
- self.canvas.updateGeometry()
- self.sp.clear();
- plt.figure(self.f.number)
- plt.subplot(111);
- nx.draw(self.G, self.pos,
- edge_color=self.edge_weights,
- node_color='#A0CBE2',
- width=map(lambda x: 3+math.log(x), self.edge_weights),
- node_shape="s",
- node_size=self.node_weights,
- #edge_cmap=plt.cm.Blues,
- edge_cmap=plt.cm.Reds,
- ax=self.sp,
- arrows=False
- )
- nx.draw_networkx_labels(self.G, self.pos,
- font_size=12)
-
- self.canvas.draw();
- self.canvas.show();
-
-class MyClient(IceRadioClient):
- def __init__(self):
- IceRadioClient.__init__(self, MAINWindow)
-
-sys.exit(MyClient().main(sys.argv))
diff --git a/gnuradio-core/src/python/gnuradio/ctrlport/icon.png b/gnuradio-core/src/python/gnuradio/ctrlport/icon.png
deleted file mode 100644
index 4beb204428..0000000000
--- a/gnuradio-core/src/python/gnuradio/ctrlport/icon.png
+++ /dev/null
Binary files differ
diff --git a/gnuradio-core/src/python/gnuradio/ctrlport/monitor.py b/gnuradio-core/src/python/gnuradio/ctrlport/monitor.py
deleted file mode 100644
index 53a571a698..0000000000
--- a/gnuradio-core/src/python/gnuradio/ctrlport/monitor.py
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2012 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-import sys, subprocess, re, signal, time, atexit, os
-from gnuradio import gr
-
-class monitor:
- def __init__(self):
- print "ControlPort Monitor running."
- self.started = False
- atexit.register(self.shutdown)
-
- def __del__(self):
- if(self.started):
- self.stop()
-
- def start(self):
- print "monitor::endpoints() = %s" % (gr.rpcmanager_get().endpoints())
- try:
- self.proc = subprocess.Popen(map(lambda a: ["gr-ctrlport-monitor",
- re.search("\d+\.\d+\.\d+\.\d+",a).group(0),
- re.search("-p (\d+)",a).group(1)],
- gr.rpcmanager_get().endpoints())[0])
- self.started = True
- except:
- self.proc = None
- print "failed to to start ControlPort Monitor on specified port"
-
- def stop(self):
- if(self.proc):
- if(self.proc.returncode == None):
- print "\tcalling stop on shutdown"
- self.proc.terminate()
- else:
- print "\tno proc to shut down, exiting"
-
- def shutdown(self):
- print "ctrlport.monitor received shutdown signal"
- if(self.started):
- self.stop()
diff --git a/gnuradio-core/src/python/gnuradio/eng_notation.py b/gnuradio-core/src/python/gnuradio/eng_notation.py
deleted file mode 100644
index d23f9005f0..0000000000
--- a/gnuradio-core/src/python/gnuradio/eng_notation.py
+++ /dev/null
@@ -1,74 +0,0 @@
-#
-# Copyright 2003 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-"""
-Display numbers as strings using engineering notation.
-"""
-
-scale_factor = {}
-scale_factor['E'] = 1e18
-scale_factor['P'] = 1e15
-scale_factor['T'] = 1e12
-scale_factor['G'] = 1e9
-scale_factor['M'] = 1e6
-scale_factor['k'] = 1e3
-scale_factor['m'] = 1e-3
-scale_factor['u'] = 1e-6
-scale_factor['n'] = 1e-9
-scale_factor['p'] = 1e-12
-scale_factor['f'] = 1e-15
-scale_factor['a'] = 1e-18
-
-def num_to_str (n):
- '''Convert a number to a string in engineering notation. E.g., 5e-9 -> 5n'''
- m = abs(n)
- if m >= 1e9:
- return "%gG" % (n * 1e-9)
- elif m >= 1e6:
- return "%gM" % (n * 1e-6)
- elif m >= 1e3:
- return "%gk" % (n * 1e-3)
- elif m >= 1:
- return "%g" % (n)
- elif m >= 1e-3:
- return "%gm" % (n * 1e3)
- elif m >= 1e-6:
- return "%gu" % (n * 1e6) # where's that mu when you need it (unicode?)
- elif m >= 1e-9:
- return "%gn" % (n * 1e9)
- elif m >= 1e-12:
- return "%gp" % (n * 1e12)
- elif m >= 1e-15:
- return "%gf" % (n * 1e15)
- else:
- return "%g" % (n)
-
-
-def str_to_num (value):
- '''Convert a string in engineering notation to a number. E.g., '15m' -> 15e-3'''
- try:
- scale = 1.0
- suffix = value[-1]
- if scale_factor.has_key (suffix):
- return float (value[0:-1]) * scale_factor[suffix]
- return float (value)
- except:
- raise RuntimeError (
- "Invalid engineering notation value: %r" % (value,))
diff --git a/gnuradio-core/src/python/gnuradio/eng_option.py b/gnuradio-core/src/python/gnuradio/eng_option.py
deleted file mode 100644
index 5d8660f0f2..0000000000
--- a/gnuradio-core/src/python/gnuradio/eng_option.py
+++ /dev/null
@@ -1,63 +0,0 @@
-#
-# Copyright 2004 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-'''Add support for engineering notation to optparse.OptionParser'''
-
-from copy import copy
-from optparse import Option, OptionValueError
-import eng_notation
-
-def check_eng_float (option, opt, value):
- try:
- return eng_notation.str_to_num(value)
- except:
- raise OptionValueError (
- "option %s: invalid engineering notation value: %r" % (opt, value))
-
-def check_intx (option, opt, value):
- try:
- return int (value, 0)
- except:
- raise OptionValueError (
- "option %s: invalid integer value: %r" % (opt, value))
-
-def check_subdev (option, opt, value):
- """
- Value has the form: (A|B)(:0|1)?
-
- Returns:
- a 2-tuple (0|1, 0|1)
- """
- d = { 'A' : (0, 0), 'A:0' : (0, 0), 'A:1' : (0, 1), 'A:2' : (0, 2),
- 'B' : (1, 0), 'B:0' : (1, 0), 'B:1' : (1, 1), 'B:2' : (1, 2) }
- try:
- return d[value.upper()]
- except:
- raise OptionValueError(
- "option %s: invalid subdev: '%r', must be one of %s" % (opt, value, ', '.join(sorted(d.keys()))))
-
-class eng_option (Option):
- TYPES = Option.TYPES + ("eng_float", "intx", "subdev")
- TYPE_CHECKER = copy (Option.TYPE_CHECKER)
- TYPE_CHECKER["eng_float"] = check_eng_float
- TYPE_CHECKER["intx"] = check_intx
- TYPE_CHECKER["subdev"] = check_subdev
-
diff --git a/gnuradio-core/src/python/gnuradio/gr/CMakeLists.txt b/gnuradio-core/src/python/gnuradio/gr/CMakeLists.txt
deleted file mode 100644
index da22a5f987..0000000000
--- a/gnuradio-core/src/python/gnuradio/gr/CMakeLists.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright 2010-2012 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-
-########################################################################
-include(GrPython)
-
-GR_PYTHON_INSTALL(FILES
- __init__.py
- exceptions.py
- gateway.py
- gr_threading.py
- gr_threading_23.py
- gr_threading_24.py
- hier_block2.py
- prefs.py
- tag_utils.py
- top_block.py
- pubsub.py
- DESTINATION ${GR_PYTHON_DIR}/gnuradio/gr
- COMPONENT "core_python"
-)
-
-########################################################################
-# Handle the unit tests
-########################################################################
-if(ENABLE_TESTING)
-include(GrTest)
-file(GLOB py_qa_test_files "qa_*.py")
-foreach(py_qa_test_file ${py_qa_test_files})
- get_filename_component(py_qa_test_name ${py_qa_test_file} NAME_WE)
- GR_ADD_TEST(${py_qa_test_name} ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B} ${py_qa_test_file})
-endforeach(py_qa_test_file)
-endif(ENABLE_TESTING)
diff --git a/gnuradio-core/src/python/gnuradio/gr/__init__.py b/gnuradio-core/src/python/gnuradio/gr/__init__.py
deleted file mode 100644
index c468437db7..0000000000
--- a/gnuradio-core/src/python/gnuradio/gr/__init__.py
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# Copyright 2003-2012 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-# The presence of this file turns this directory into a Python package
-
-"""
-Core contents.
-"""
-
-# This is the main GNU Radio python module.
-# We pull the swig output and the other modules into the gnuradio.gr namespace
-
-from gnuradio_core import *
-from exceptions import *
-from hier_block2 import *
-from top_block import *
-from gateway import basic_block, sync_block, decim_block, interp_block
-from tag_utils import tag_to_python, tag_to_pmt
-
-# Force the preference database to be initialized
-prefs = gr_prefs.singleton
diff --git a/gnuradio-core/src/python/gnuradio/gr/exceptions.py b/gnuradio-core/src/python/gnuradio/gr/exceptions.py
deleted file mode 100644
index dba04750bc..0000000000
--- a/gnuradio-core/src/python/gnuradio/gr/exceptions.py
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# Copyright 2004 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-
-class NotDAG (Exception):
- """Not a directed acyclic graph"""
- pass
-
-class CantHappen (Exception):
- """Can't happen"""
- pass
diff --git a/gnuradio-core/src/python/gnuradio/gr/gateway.py b/gnuradio-core/src/python/gnuradio/gr/gateway.py
deleted file mode 100644
index c25755bb57..0000000000
--- a/gnuradio-core/src/python/gnuradio/gr/gateway.py
+++ /dev/null
@@ -1,243 +0,0 @@
-#
-# Copyright 2011-2012 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-import gnuradio_core as gr_core
-from gnuradio_core import io_signature, io_signaturev
-from gnuradio_core import gr_block_gw_message_type
-from gnuradio_core import block_gateway
-import numpy
-
-########################################################################
-# Magic to turn pointers into numpy arrays
-# http://docs.scipy.org/doc/numpy/reference/arrays.interface.html
-########################################################################
-def pointer_to_ndarray(addr, dtype, nitems):
- class array_like:
- __array_interface__ = {
- 'data' : (int(addr), False),
- 'typestr' : dtype.base.str,
- 'descr' : dtype.base.descr,
- 'shape' : (nitems,) + dtype.shape,
- 'strides' : None,
- 'version' : 3
- }
- return numpy.asarray(array_like()).view(dtype.base)
-
-########################################################################
-# Handler that does callbacks from C++
-########################################################################
-class gateway_handler(gr_core.feval_ll):
-
- #dont put a constructor, it wont work
-
- def init(self, callback):
- self._callback = callback
-
- def eval(self, arg):
- try: self._callback()
- except Exception as ex:
- print("handler caught exception: %s"%ex)
- import traceback; traceback.print_exc()
- raise ex
- return 0
-
-########################################################################
-# Handler that does callbacks from C++
-########################################################################
-class msg_handler(gr_core.feval_p):
-
- #dont put a constructor, it wont work
-
- def init(self, callback):
- self._callback = callback
-
- def eval(self, arg):
- try: self._callback(arg)
- except Exception as ex:
- print("handler caught exception: %s"%ex)
- import traceback; traceback.print_exc()
- raise ex
- return 0
-
-########################################################################
-# The guts that make this into a gr block
-########################################################################
-class gateway_block(object):
-
- def __init__(self, name, in_sig, out_sig, work_type, factor):
-
- #ensure that the sigs are iterable dtypes
- def sig_to_dtype_sig(sig):
- if sig is None: sig = ()
- return map(numpy.dtype, sig)
- self.__in_sig = sig_to_dtype_sig(in_sig)
- self.__out_sig = sig_to_dtype_sig(out_sig)
-
- #cache the ranges to iterate when dispatching work
- self.__in_indexes = range(len(self.__in_sig))
- self.__out_indexes = range(len(self.__out_sig))
-
- #convert the signatures into gr.io_signatures
- def sig_to_gr_io_sigv(sig):
- if not len(sig): return io_signature(0, 0, 0)
- return io_signaturev(len(sig), len(sig), [s.itemsize for s in sig])
- gr_in_sig = sig_to_gr_io_sigv(self.__in_sig)
- gr_out_sig = sig_to_gr_io_sigv(self.__out_sig)
-
- #create internal gateway block
- self.__handler = gateway_handler()
- self.__handler.init(self.__gr_block_handle)
- self.__gateway = block_gateway(
- self.__handler, name, gr_in_sig, gr_out_sig, work_type, factor)
- self.__message = self.__gateway.gr_block_message()
-
- #dict to keep references to all message handlers
- self.__msg_handlers = {}
-
- #register gr_block functions
- prefix = 'gr_block__'
- for attr in [x for x in dir(self.__gateway) if x.startswith(prefix)]:
- setattr(self, attr.replace(prefix, ''), getattr(self.__gateway, attr))
- self.pop_msg_queue = lambda: gr_core.gr_block_gw_pop_msg_queue_safe(self.__gateway)
-
- def to_basic_block(self):
- """
- Makes this block connectable by hier/top block python
- """
- return self.__gateway.to_basic_block()
-
- def __gr_block_handle(self):
- """
- Dispatch tasks according to the action type specified in the message.
- """
- if self.__message.action == gr_block_gw_message_type.ACTION_GENERAL_WORK:
- self.__message.general_work_args_return_value = self.general_work(
-
- input_items=[pointer_to_ndarray(
- self.__message.general_work_args_input_items[i],
- self.__in_sig[i],
- self.__message.general_work_args_ninput_items[i]
- ) for i in self.__in_indexes],
-
- output_items=[pointer_to_ndarray(
- self.__message.general_work_args_output_items[i],
- self.__out_sig[i],
- self.__message.general_work_args_noutput_items
- ) for i in self.__out_indexes],
- )
-
- elif self.__message.action == gr_block_gw_message_type.ACTION_WORK:
- self.__message.work_args_return_value = self.work(
-
- input_items=[pointer_to_ndarray(
- self.__message.work_args_input_items[i],
- self.__in_sig[i],
- self.__message.work_args_ninput_items
- ) for i in self.__in_indexes],
-
- output_items=[pointer_to_ndarray(
- self.__message.work_args_output_items[i],
- self.__out_sig[i],
- self.__message.work_args_noutput_items
- ) for i in self.__out_indexes],
- )
-
- elif self.__message.action == gr_block_gw_message_type.ACTION_FORECAST:
- self.forecast(
- noutput_items=self.__message.forecast_args_noutput_items,
- ninput_items_required=self.__message.forecast_args_ninput_items_required,
- )
-
- elif self.__message.action == gr_block_gw_message_type.ACTION_START:
- self.__message.start_args_return_value = self.start()
-
- elif self.__message.action == gr_block_gw_message_type.ACTION_STOP:
- self.__message.stop_args_return_value = self.stop()
-
- def forecast(self, noutput_items, ninput_items_required):
- """
- forecast is only called from a general block
- this is the default implementation
- """
- for ninput_item in ninput_items_required:
- ninput_item = noutput_items + self.history() - 1;
- return
-
- def general_work(self, *args, **kwargs):
- """general work to be overloaded in a derived class"""
- raise NotImplementedError("general work not implemented")
-
- def work(self, *args, **kwargs):
- """work to be overloaded in a derived class"""
- raise NotImplementedError("work not implemented")
-
- def start(self): return True
- def stop(self): return True
-
- def set_msg_handler(self, which_port, handler_func):
- handler = msg_handler()
- handler.init(handler_func)
- self.__gateway.set_msg_handler_feval(which_port, handler)
- # Save handler object in class so it's not garbage collected
- self.__msg_handlers[which_port] = handler
-
-########################################################################
-# Wrappers for the user to inherit from
-########################################################################
-class basic_block(gateway_block):
- def __init__(self, name, in_sig, out_sig):
- gateway_block.__init__(self,
- name=name,
- in_sig=in_sig,
- out_sig=out_sig,
- work_type=gr_core.GR_BLOCK_GW_WORK_GENERAL,
- factor=1, #not relevant factor
- )
-
-class sync_block(gateway_block):
- def __init__(self, name, in_sig, out_sig):
- gateway_block.__init__(self,
- name=name,
- in_sig=in_sig,
- out_sig=out_sig,
- work_type=gr_core.GR_BLOCK_GW_WORK_SYNC,
- factor=1,
- )
-
-class decim_block(gateway_block):
- def __init__(self, name, in_sig, out_sig, decim):
- gateway_block.__init__(self,
- name=name,
- in_sig=in_sig,
- out_sig=out_sig,
- work_type=gr_core.GR_BLOCK_GW_WORK_DECIM,
- factor=decim,
- )
-
-class interp_block(gateway_block):
- def __init__(self, name, in_sig, out_sig, interp):
- gateway_block.__init__(self,
- name=name,
- in_sig=in_sig,
- out_sig=out_sig,
- work_type=gr_core.GR_BLOCK_GW_WORK_INTERP,
- factor=interp,
- )
diff --git a/gnuradio-core/src/python/gnuradio/gr/gr_threading.py b/gnuradio-core/src/python/gnuradio/gr/gr_threading.py
deleted file mode 100644
index 5d6f0fdaf9..0000000000
--- a/gnuradio-core/src/python/gnuradio/gr/gr_threading.py
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# Copyright 2005 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from sys import version_info as _version_info
-
-# import patched version of standard threading module
-
-if _version_info[0:2] == (2, 3):
- #print "Importing gr_threading_23"
- from gr_threading_23 import *
-elif _version_info[0:2] == (2, 4):
- #print "Importing gr_threading_24"
- from gr_threading_24 import *
-else:
- # assume the patch was applied...
- #print "Importing system provided threading"
- from threading import *
diff --git a/gnuradio-core/src/python/gnuradio/gr/gr_threading_23.py b/gnuradio-core/src/python/gnuradio/gr/gr_threading_23.py
deleted file mode 100644
index dee8034c1c..0000000000
--- a/gnuradio-core/src/python/gnuradio/gr/gr_threading_23.py
+++ /dev/null
@@ -1,724 +0,0 @@
-"""Thread module emulating a subset of Java's threading model."""
-
-# This started life as the threading.py module of Python 2.3
-# It's been patched to fix a problem with join, where a KeyboardInterrupt
-# caused a lock to be left in the acquired state.
-
-import sys as _sys
-
-try:
- import thread
-except ImportError:
- del _sys.modules[__name__]
- raise
-
-from StringIO import StringIO as _StringIO
-from time import time as _time, sleep as _sleep
-from traceback import print_exc as _print_exc
-
-# Rename some stuff so "from threading import *" is safe
-__all__ = ['activeCount', 'Condition', 'currentThread', 'enumerate', 'Event',
- 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread',
- 'Timer', 'setprofile', 'settrace']
-
-_start_new_thread = thread.start_new_thread
-_allocate_lock = thread.allocate_lock
-_get_ident = thread.get_ident
-ThreadError = thread.error
-del thread
-
-
-# Debug support (adapted from ihooks.py).
-# All the major classes here derive from _Verbose. We force that to
-# be a new-style class so that all the major classes here are new-style.
-# This helps debugging (type(instance) is more revealing for instances
-# of new-style classes).
-
-_VERBOSE = False
-
-if __debug__:
-
- class _Verbose(object):
-
- def __init__(self, verbose=None):
- if verbose is None:
- verbose = _VERBOSE
- self.__verbose = verbose
-
- def _note(self, format, *args):
- if self.__verbose:
- format = format % args
- format = "%s: %s\n" % (
- currentThread().getName(), format)
- _sys.stderr.write(format)
-
-else:
- # Disable this when using "python -O"
- class _Verbose(object):
- def __init__(self, verbose=None):
- pass
- def _note(self, *args):
- pass
-
-# Support for profile and trace hooks
-
-_profile_hook = None
-_trace_hook = None
-
-def setprofile(func):
- global _profile_hook
- _profile_hook = func
-
-def settrace(func):
- global _trace_hook
- _trace_hook = func
-
-# Synchronization classes
-
-Lock = _allocate_lock
-
-def RLock(*args, **kwargs):
- return _RLock(*args, **kwargs)
-
-class _RLock(_Verbose):
-
- def __init__(self, verbose=None):
- _Verbose.__init__(self, verbose)
- self.__block = _allocate_lock()
- self.__owner = None
- self.__count = 0
-
- def __repr__(self):
- return "<%s(%s, %d)>" % (
- self.__class__.__name__,
- self.__owner and self.__owner.getName(),
- self.__count)
-
- def acquire(self, blocking=1):
- me = currentThread()
- if self.__owner is me:
- self.__count = self.__count + 1
- if __debug__:
- self._note("%s.acquire(%s): recursive success", self, blocking)
- return 1
- rc = self.__block.acquire(blocking)
- if rc:
- self.__owner = me
- self.__count = 1
- if __debug__:
- self._note("%s.acquire(%s): initial succes", self, blocking)
- else:
- if __debug__:
- self._note("%s.acquire(%s): failure", self, blocking)
- return rc
-
- def release(self):
- me = currentThread()
- assert self.__owner is me, "release() of un-acquire()d lock"
- self.__count = count = self.__count - 1
- if not count:
- self.__owner = None
- self.__block.release()
- if __debug__:
- self._note("%s.release(): final release", self)
- else:
- if __debug__:
- self._note("%s.release(): non-final release", self)
-
- # Internal methods used by condition variables
-
- def _acquire_restore(self, (count, owner)):
- self.__block.acquire()
- self.__count = count
- self.__owner = owner
- if __debug__:
- self._note("%s._acquire_restore()", self)
-
- def _release_save(self):
- if __debug__:
- self._note("%s._release_save()", self)
- count = self.__count
- self.__count = 0
- owner = self.__owner
- self.__owner = None
- self.__block.release()
- return (count, owner)
-
- def _is_owned(self):
- return self.__owner is currentThread()
-
-
-def Condition(*args, **kwargs):
- return _Condition(*args, **kwargs)
-
-class _Condition(_Verbose):
-
- def __init__(self, lock=None, verbose=None):
- _Verbose.__init__(self, verbose)
- if lock is None:
- lock = RLock()
- self.__lock = lock
- # Export the lock's acquire() and release() methods
- self.acquire = lock.acquire
- self.release = lock.release
- # If the lock defines _release_save() and/or _acquire_restore(),
- # these override the default implementations (which just call
- # release() and acquire() on the lock). Ditto for _is_owned().
- try:
- self._release_save = lock._release_save
- except AttributeError:
- pass
- try:
- self._acquire_restore = lock._acquire_restore
- except AttributeError:
- pass
- try:
- self._is_owned = lock._is_owned
- except AttributeError:
- pass
- self.__waiters = []
-
- def __repr__(self):
- return "<Condition(%s, %d)>" % (self.__lock, len(self.__waiters))
-
- def _release_save(self):
- self.__lock.release() # No state to save
-
- def _acquire_restore(self, x):
- self.__lock.acquire() # Ignore saved state
-
- def _is_owned(self):
- # Return True if lock is owned by currentThread.
- # This method is called only if __lock doesn't have _is_owned().
- if self.__lock.acquire(0):
- self.__lock.release()
- return False
- else:
- return True
-
- def wait(self, timeout=None):
- currentThread() # for side-effect
- assert self._is_owned(), "wait() of un-acquire()d lock"
- waiter = _allocate_lock()
- waiter.acquire()
- self.__waiters.append(waiter)
- saved_state = self._release_save()
- try: # restore state no matter what (e.g., KeyboardInterrupt)
- if timeout is None:
- waiter.acquire()
- if __debug__:
- self._note("%s.wait(): got it", self)
- else:
- # Balancing act: We can't afford a pure busy loop, so we
- # have to sleep; but if we sleep the whole timeout time,
- # we'll be unresponsive. The scheme here sleeps very
- # little at first, longer as time goes on, but never longer
- # than 20 times per second (or the timeout time remaining).
- endtime = _time() + timeout
- delay = 0.0005 # 500 us -> initial delay of 1 ms
- while True:
- gotit = waiter.acquire(0)
- if gotit:
- break
- remaining = endtime - _time()
- if remaining <= 0:
- break
- delay = min(delay * 2, remaining, .05)
- _sleep(delay)
- if not gotit:
- if __debug__:
- self._note("%s.wait(%s): timed out", self, timeout)
- try:
- self.__waiters.remove(waiter)
- except ValueError:
- pass
- else:
- if __debug__:
- self._note("%s.wait(%s): got it", self, timeout)
- finally:
- self._acquire_restore(saved_state)
-
- def notify(self, n=1):
- currentThread() # for side-effect
- assert self._is_owned(), "notify() of un-acquire()d lock"
- __waiters = self.__waiters
- waiters = __waiters[:n]
- if not waiters:
- if __debug__:
- self._note("%s.notify(): no waiters", self)
- return
- self._note("%s.notify(): notifying %d waiter%s", self, n,
- n!=1 and "s" or "")
- for waiter in waiters:
- waiter.release()
- try:
- __waiters.remove(waiter)
- except ValueError:
- pass
-
- def notifyAll(self):
- self.notify(len(self.__waiters))
-
-
-def Semaphore(*args, **kwargs):
- return _Semaphore(*args, **kwargs)
-
-class _Semaphore(_Verbose):
-
- # After Tim Peters' semaphore class, but not quite the same (no maximum)
-
- def __init__(self, value=1, verbose=None):
- assert value >= 0, "Semaphore initial value must be >= 0"
- _Verbose.__init__(self, verbose)
- self.__cond = Condition(Lock())
- self.__value = value
-
- def acquire(self, blocking=1):
- rc = False
- self.__cond.acquire()
- while self.__value == 0:
- if not blocking:
- break
- if __debug__:
- self._note("%s.acquire(%s): blocked waiting, value=%s",
- self, blocking, self.__value)
- self.__cond.wait()
- else:
- self.__value = self.__value - 1
- if __debug__:
- self._note("%s.acquire: success, value=%s",
- self, self.__value)
- rc = True
- self.__cond.release()
- return rc
-
- def release(self):
- self.__cond.acquire()
- self.__value = self.__value + 1
- if __debug__:
- self._note("%s.release: success, value=%s",
- self, self.__value)
- self.__cond.notify()
- self.__cond.release()
-
-
-def BoundedSemaphore(*args, **kwargs):
- return _BoundedSemaphore(*args, **kwargs)
-
-class _BoundedSemaphore(_Semaphore):
- """Semaphore that checks that # releases is <= # acquires"""
- def __init__(self, value=1, verbose=None):
- _Semaphore.__init__(self, value, verbose)
- self._initial_value = value
-
- def release(self):
- if self._Semaphore__value >= self._initial_value:
- raise ValueError, "Semaphore released too many times"
- return _Semaphore.release(self)
-
-
-def Event(*args, **kwargs):
- return _Event(*args, **kwargs)
-
-class _Event(_Verbose):
-
- # After Tim Peters' event class (without is_posted())
-
- def __init__(self, verbose=None):
- _Verbose.__init__(self, verbose)
- self.__cond = Condition(Lock())
- self.__flag = False
-
- def isSet(self):
- return self.__flag
-
- def set(self):
- self.__cond.acquire()
- try:
- self.__flag = True
- self.__cond.notifyAll()
- finally:
- self.__cond.release()
-
- def clear(self):
- self.__cond.acquire()
- try:
- self.__flag = False
- finally:
- self.__cond.release()
-
- def wait(self, timeout=None):
- self.__cond.acquire()
- try:
- if not self.__flag:
- self.__cond.wait(timeout)
- finally:
- self.__cond.release()
-
-# Helper to generate new thread names
-_counter = 0
-def _newname(template="Thread-%d"):
- global _counter
- _counter = _counter + 1
- return template % _counter
-
-# Active thread administration
-_active_limbo_lock = _allocate_lock()
-_active = {}
-_limbo = {}
-
-
-# Main class for threads
-
-class Thread(_Verbose):
-
- __initialized = False
-
- def __init__(self, group=None, target=None, name=None,
- args=(), kwargs={}, verbose=None):
- assert group is None, "group argument must be None for now"
- _Verbose.__init__(self, verbose)
- self.__target = target
- self.__name = str(name or _newname())
- self.__args = args
- self.__kwargs = kwargs
- self.__daemonic = self._set_daemon()
- self.__started = False
- self.__stopped = False
- self.__block = Condition(Lock())
- self.__initialized = True
-
- def _set_daemon(self):
- # Overridden in _MainThread and _DummyThread
- return currentThread().isDaemon()
-
- def __repr__(self):
- assert self.__initialized, "Thread.__init__() was not called"
- status = "initial"
- if self.__started:
- status = "started"
- if self.__stopped:
- status = "stopped"
- if self.__daemonic:
- status = status + " daemon"
- return "<%s(%s, %s)>" % (self.__class__.__name__, self.__name, status)
-
- def start(self):
- assert self.__initialized, "Thread.__init__() not called"
- assert not self.__started, "thread already started"
- if __debug__:
- self._note("%s.start(): starting thread", self)
- _active_limbo_lock.acquire()
- _limbo[self] = self
- _active_limbo_lock.release()
- _start_new_thread(self.__bootstrap, ())
- self.__started = True
- _sleep(0.000001) # 1 usec, to let the thread run (Solaris hack)
-
- def run(self):
- if self.__target:
- self.__target(*self.__args, **self.__kwargs)
-
- def __bootstrap(self):
- try:
- self.__started = True
- _active_limbo_lock.acquire()
- _active[_get_ident()] = self
- del _limbo[self]
- _active_limbo_lock.release()
- if __debug__:
- self._note("%s.__bootstrap(): thread started", self)
-
- if _trace_hook:
- self._note("%s.__bootstrap(): registering trace hook", self)
- _sys.settrace(_trace_hook)
- if _profile_hook:
- self._note("%s.__bootstrap(): registering profile hook", self)
- _sys.setprofile(_profile_hook)
-
- try:
- self.run()
- except SystemExit:
- if __debug__:
- self._note("%s.__bootstrap(): raised SystemExit", self)
- except:
- if __debug__:
- self._note("%s.__bootstrap(): unhandled exception", self)
- s = _StringIO()
- _print_exc(file=s)
- _sys.stderr.write("Exception in thread %s:\n%s\n" %
- (self.getName(), s.getvalue()))
- else:
- if __debug__:
- self._note("%s.__bootstrap(): normal return", self)
- finally:
- self.__stop()
- try:
- self.__delete()
- except:
- pass
-
- def __stop(self):
- self.__block.acquire()
- self.__stopped = True
- self.__block.notifyAll()
- self.__block.release()
-
- def __delete(self):
- _active_limbo_lock.acquire()
- del _active[_get_ident()]
- _active_limbo_lock.release()
-
- def join(self, timeout=None):
- assert self.__initialized, "Thread.__init__() not called"
- assert self.__started, "cannot join thread before it is started"
- assert self is not currentThread(), "cannot join current thread"
- if __debug__:
- if not self.__stopped:
- self._note("%s.join(): waiting until thread stops", self)
- self.__block.acquire()
- try:
- if timeout is None:
- while not self.__stopped:
- self.__block.wait()
- if __debug__:
- self._note("%s.join(): thread stopped", self)
- else:
- deadline = _time() + timeout
- while not self.__stopped:
- delay = deadline - _time()
- if delay <= 0:
- if __debug__:
- self._note("%s.join(): timed out", self)
- break
- self.__block.wait(delay)
- else:
- if __debug__:
- self._note("%s.join(): thread stopped", self)
- finally:
- self.__block.release()
-
- def getName(self):
- assert self.__initialized, "Thread.__init__() not called"
- return self.__name
-
- def setName(self, name):
- assert self.__initialized, "Thread.__init__() not called"
- self.__name = str(name)
-
- def isAlive(self):
- assert self.__initialized, "Thread.__init__() not called"
- return self.__started and not self.__stopped
-
- def isDaemon(self):
- assert self.__initialized, "Thread.__init__() not called"
- return self.__daemonic
-
- def setDaemon(self, daemonic):
- assert self.__initialized, "Thread.__init__() not called"
- assert not self.__started, "cannot set daemon status of active thread"
- self.__daemonic = daemonic
-
-# The timer class was contributed by Itamar Shtull-Trauring
-
-def Timer(*args, **kwargs):
- return _Timer(*args, **kwargs)
-
-class _Timer(Thread):
- """Call a function after a specified number of seconds:
-
- t = Timer(30.0, f, args=[], kwargs={})
- t.start()
- t.cancel() # stop the timer's action if it's still waiting
- """
-
- def __init__(self, interval, function, args=[], kwargs={}):
- Thread.__init__(self)
- self.interval = interval
- self.function = function
- self.args = args
- self.kwargs = kwargs
- self.finished = Event()
-
- def cancel(self):
- """Stop the timer if it hasn't finished yet"""
- self.finished.set()
-
- def run(self):
- self.finished.wait(self.interval)
- if not self.finished.isSet():
- self.function(*self.args, **self.kwargs)
- self.finished.set()
-
-# Special thread class to represent the main thread
-# This is garbage collected through an exit handler
-
-class _MainThread(Thread):
-
- def __init__(self):
- Thread.__init__(self, name="MainThread")
- self._Thread__started = True
- _active_limbo_lock.acquire()
- _active[_get_ident()] = self
- _active_limbo_lock.release()
- import atexit
- atexit.register(self.__exitfunc)
-
- def _set_daemon(self):
- return False
-
- def __exitfunc(self):
- self._Thread__stop()
- t = _pickSomeNonDaemonThread()
- if t:
- if __debug__:
- self._note("%s: waiting for other threads", self)
- while t:
- t.join()
- t = _pickSomeNonDaemonThread()
- if __debug__:
- self._note("%s: exiting", self)
- self._Thread__delete()
-
-def _pickSomeNonDaemonThread():
- for t in enumerate():
- if not t.isDaemon() and t.isAlive():
- return t
- return None
-
-
-# Dummy thread class to represent threads not started here.
-# These aren't garbage collected when they die,
-# nor can they be waited for.
-# Their purpose is to return *something* from currentThread().
-# They are marked as daemon threads so we won't wait for them
-# when we exit (conform previous semantics).
-
-class _DummyThread(Thread):
-
- def __init__(self):
- Thread.__init__(self, name=_newname("Dummy-%d"))
- self._Thread__started = True
- _active_limbo_lock.acquire()
- _active[_get_ident()] = self
- _active_limbo_lock.release()
-
- def _set_daemon(self):
- return True
-
- def join(self, timeout=None):
- assert False, "cannot join a dummy thread"
-
-
-# Global API functions
-
-def currentThread():
- try:
- return _active[_get_ident()]
- except KeyError:
- ##print "currentThread(): no current thread for", _get_ident()
- return _DummyThread()
-
-def activeCount():
- _active_limbo_lock.acquire()
- count = len(_active) + len(_limbo)
- _active_limbo_lock.release()
- return count
-
-def enumerate():
- _active_limbo_lock.acquire()
- active = _active.values() + _limbo.values()
- _active_limbo_lock.release()
- return active
-
-# Create the main thread object
-
-_MainThread()
-
-
-# Self-test code
-
-def _test():
-
- class BoundedQueue(_Verbose):
-
- def __init__(self, limit):
- _Verbose.__init__(self)
- self.mon = RLock()
- self.rc = Condition(self.mon)
- self.wc = Condition(self.mon)
- self.limit = limit
- self.queue = []
-
- def put(self, item):
- self.mon.acquire()
- while len(self.queue) >= self.limit:
- self._note("put(%s): queue full", item)
- self.wc.wait()
- self.queue.append(item)
- self._note("put(%s): appended, length now %d",
- item, len(self.queue))
- self.rc.notify()
- self.mon.release()
-
- def get(self):
- self.mon.acquire()
- while not self.queue:
- self._note("get(): queue empty")
- self.rc.wait()
- item = self.queue.pop(0)
- self._note("get(): got %s, %d left", item, len(self.queue))
- self.wc.notify()
- self.mon.release()
- return item
-
- class ProducerThread(Thread):
-
- def __init__(self, queue, quota):
- Thread.__init__(self, name="Producer")
- self.queue = queue
- self.quota = quota
-
- def run(self):
- from random import random
- counter = 0
- while counter < self.quota:
- counter = counter + 1
- self.queue.put("%s.%d" % (self.getName(), counter))
- _sleep(random() * 0.00001)
-
-
- class ConsumerThread(Thread):
-
- def __init__(self, queue, count):
- Thread.__init__(self, name="Consumer")
- self.queue = queue
- self.count = count
-
- def run(self):
- while self.count > 0:
- item = self.queue.get()
- print item
- self.count = self.count - 1
-
- NP = 3
- QL = 4
- NI = 5
-
- Q = BoundedQueue(QL)
- P = []
- for i in range(NP):
- t = ProducerThread(Q, NI)
- t.setName("Producer-%d" % (i+1))
- P.append(t)
- C = ConsumerThread(Q, NI*NP)
- for t in P:
- t.start()
- _sleep(0.000001)
- C.start()
- for t in P:
- t.join()
- C.join()
-
-if __name__ == '__main__':
- _test()
diff --git a/gnuradio-core/src/python/gnuradio/gr/gr_threading_24.py b/gnuradio-core/src/python/gnuradio/gr/gr_threading_24.py
deleted file mode 100644
index 8539bfc047..0000000000
--- a/gnuradio-core/src/python/gnuradio/gr/gr_threading_24.py
+++ /dev/null
@@ -1,793 +0,0 @@
-"""Thread module emulating a subset of Java's threading model."""
-
-# This started life as the threading.py module of Python 2.4
-# It's been patched to fix a problem with join, where a KeyboardInterrupt
-# caused a lock to be left in the acquired state.
-
-import sys as _sys
-
-try:
- import thread
-except ImportError:
- del _sys.modules[__name__]
- raise
-
-from time import time as _time, sleep as _sleep
-from traceback import format_exc as _format_exc
-from collections import deque
-
-# Rename some stuff so "from threading import *" is safe
-__all__ = ['activeCount', 'Condition', 'currentThread', 'enumerate', 'Event',
- 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread',
- 'Timer', 'setprofile', 'settrace', 'local']
-
-_start_new_thread = thread.start_new_thread
-_allocate_lock = thread.allocate_lock
-_get_ident = thread.get_ident
-ThreadError = thread.error
-del thread
-
-
-# Debug support (adapted from ihooks.py).
-# All the major classes here derive from _Verbose. We force that to
-# be a new-style class so that all the major classes here are new-style.
-# This helps debugging (type(instance) is more revealing for instances
-# of new-style classes).
-
-_VERBOSE = False
-
-if __debug__:
-
- class _Verbose(object):
-
- def __init__(self, verbose=None):
- if verbose is None:
- verbose = _VERBOSE
- self.__verbose = verbose
-
- def _note(self, format, *args):
- if self.__verbose:
- format = format % args
- format = "%s: %s\n" % (
- currentThread().getName(), format)
- _sys.stderr.write(format)
-
-else:
- # Disable this when using "python -O"
- class _Verbose(object):
- def __init__(self, verbose=None):
- pass
- def _note(self, *args):
- pass
-
-# Support for profile and trace hooks
-
-_profile_hook = None
-_trace_hook = None
-
-def setprofile(func):
- global _profile_hook
- _profile_hook = func
-
-def settrace(func):
- global _trace_hook
- _trace_hook = func
-
-# Synchronization classes
-
-Lock = _allocate_lock
-
-def RLock(*args, **kwargs):
- return _RLock(*args, **kwargs)
-
-class _RLock(_Verbose):
-
- def __init__(self, verbose=None):
- _Verbose.__init__(self, verbose)
- self.__block = _allocate_lock()
- self.__owner = None
- self.__count = 0
-
- def __repr__(self):
- return "<%s(%s, %d)>" % (
- self.__class__.__name__,
- self.__owner and self.__owner.getName(),
- self.__count)
-
- def acquire(self, blocking=1):
- me = currentThread()
- if self.__owner is me:
- self.__count = self.__count + 1
- if __debug__:
- self._note("%s.acquire(%s): recursive success", self, blocking)
- return 1
- rc = self.__block.acquire(blocking)
- if rc:
- self.__owner = me
- self.__count = 1
- if __debug__:
- self._note("%s.acquire(%s): initial succes", self, blocking)
- else:
- if __debug__:
- self._note("%s.acquire(%s): failure", self, blocking)
- return rc
-
- def release(self):
- me = currentThread()
- assert self.__owner is me, "release() of un-acquire()d lock"
- self.__count = count = self.__count - 1
- if not count:
- self.__owner = None
- self.__block.release()
- if __debug__:
- self._note("%s.release(): final release", self)
- else:
- if __debug__:
- self._note("%s.release(): non-final release", self)
-
- # Internal methods used by condition variables
-
- def _acquire_restore(self, (count, owner)):
- self.__block.acquire()
- self.__count = count
- self.__owner = owner
- if __debug__:
- self._note("%s._acquire_restore()", self)
-
- def _release_save(self):
- if __debug__:
- self._note("%s._release_save()", self)
- count = self.__count
- self.__count = 0
- owner = self.__owner
- self.__owner = None
- self.__block.release()
- return (count, owner)
-
- def _is_owned(self):
- return self.__owner is currentThread()
-
-
-def Condition(*args, **kwargs):
- return _Condition(*args, **kwargs)
-
-class _Condition(_Verbose):
-
- def __init__(self, lock=None, verbose=None):
- _Verbose.__init__(self, verbose)
- if lock is None:
- lock = RLock()
- self.__lock = lock
- # Export the lock's acquire() and release() methods
- self.acquire = lock.acquire
- self.release = lock.release
- # If the lock defines _release_save() and/or _acquire_restore(),
- # these override the default implementations (which just call
- # release() and acquire() on the lock). Ditto for _is_owned().
- try:
- self._release_save = lock._release_save
- except AttributeError:
- pass
- try:
- self._acquire_restore = lock._acquire_restore
- except AttributeError:
- pass
- try:
- self._is_owned = lock._is_owned
- except AttributeError:
- pass
- self.__waiters = []
-
- def __repr__(self):
- return "<Condition(%s, %d)>" % (self.__lock, len(self.__waiters))
-
- def _release_save(self):
- self.__lock.release() # No state to save
-
- def _acquire_restore(self, x):
- self.__lock.acquire() # Ignore saved state
-
- def _is_owned(self):
- # Return True if lock is owned by currentThread.
- # This method is called only if __lock doesn't have _is_owned().
- if self.__lock.acquire(0):
- self.__lock.release()
- return False
- else:
- return True
-
- def wait(self, timeout=None):
- assert self._is_owned(), "wait() of un-acquire()d lock"
- waiter = _allocate_lock()
- waiter.acquire()
- self.__waiters.append(waiter)
- saved_state = self._release_save()
- try: # restore state no matter what (e.g., KeyboardInterrupt)
- if timeout is None:
- waiter.acquire()
- if __debug__:
- self._note("%s.wait(): got it", self)
- else:
- # Balancing act: We can't afford a pure busy loop, so we
- # have to sleep; but if we sleep the whole timeout time,
- # we'll be unresponsive. The scheme here sleeps very
- # little at first, longer as time goes on, but never longer
- # than 20 times per second (or the timeout time remaining).
- endtime = _time() + timeout
- delay = 0.0005 # 500 us -> initial delay of 1 ms
- while True:
- gotit = waiter.acquire(0)
- if gotit:
- break
- remaining = endtime - _time()
- if remaining <= 0:
- break
- delay = min(delay * 2, remaining, .05)
- _sleep(delay)
- if not gotit:
- if __debug__:
- self._note("%s.wait(%s): timed out", self, timeout)
- try:
- self.__waiters.remove(waiter)
- except ValueError:
- pass
- else:
- if __debug__:
- self._note("%s.wait(%s): got it", self, timeout)
- finally:
- self._acquire_restore(saved_state)
-
- def notify(self, n=1):
- assert self._is_owned(), "notify() of un-acquire()d lock"
- __waiters = self.__waiters
- waiters = __waiters[:n]
- if not waiters:
- if __debug__:
- self._note("%s.notify(): no waiters", self)
- return
- self._note("%s.notify(): notifying %d waiter%s", self, n,
- n!=1 and "s" or "")
- for waiter in waiters:
- waiter.release()
- try:
- __waiters.remove(waiter)
- except ValueError:
- pass
-
- def notifyAll(self):
- self.notify(len(self.__waiters))
-
-
-def Semaphore(*args, **kwargs):
- return _Semaphore(*args, **kwargs)
-
-class _Semaphore(_Verbose):
-
- # After Tim Peters' semaphore class, but not quite the same (no maximum)
-
- def __init__(self, value=1, verbose=None):
- assert value >= 0, "Semaphore initial value must be >= 0"
- _Verbose.__init__(self, verbose)
- self.__cond = Condition(Lock())
- self.__value = value
-
- def acquire(self, blocking=1):
- rc = False
- self.__cond.acquire()
- while self.__value == 0:
- if not blocking:
- break
- if __debug__:
- self._note("%s.acquire(%s): blocked waiting, value=%s",
- self, blocking, self.__value)
- self.__cond.wait()
- else:
- self.__value = self.__value - 1
- if __debug__:
- self._note("%s.acquire: success, value=%s",
- self, self.__value)
- rc = True
- self.__cond.release()
- return rc
-
- def release(self):
- self.__cond.acquire()
- self.__value = self.__value + 1
- if __debug__:
- self._note("%s.release: success, value=%s",
- self, self.__value)
- self.__cond.notify()
- self.__cond.release()
-
-
-def BoundedSemaphore(*args, **kwargs):
- return _BoundedSemaphore(*args, **kwargs)
-
-class _BoundedSemaphore(_Semaphore):
- """Semaphore that checks that # releases is <= # acquires"""
- def __init__(self, value=1, verbose=None):
- _Semaphore.__init__(self, value, verbose)
- self._initial_value = value
-
- def release(self):
- if self._Semaphore__value >= self._initial_value:
- raise ValueError, "Semaphore released too many times"
- return _Semaphore.release(self)
-
-
-def Event(*args, **kwargs):
- return _Event(*args, **kwargs)
-
-class _Event(_Verbose):
-
- # After Tim Peters' event class (without is_posted())
-
- def __init__(self, verbose=None):
- _Verbose.__init__(self, verbose)
- self.__cond = Condition(Lock())
- self.__flag = False
-
- def isSet(self):
- return self.__flag
-
- def set(self):
- self.__cond.acquire()
- try:
- self.__flag = True
- self.__cond.notifyAll()
- finally:
- self.__cond.release()
-
- def clear(self):
- self.__cond.acquire()
- try:
- self.__flag = False
- finally:
- self.__cond.release()
-
- def wait(self, timeout=None):
- self.__cond.acquire()
- try:
- if not self.__flag:
- self.__cond.wait(timeout)
- finally:
- self.__cond.release()
-
-# Helper to generate new thread names
-_counter = 0
-def _newname(template="Thread-%d"):
- global _counter
- _counter = _counter + 1
- return template % _counter
-
-# Active thread administration
-_active_limbo_lock = _allocate_lock()
-_active = {}
-_limbo = {}
-
-
-# Main class for threads
-
-class Thread(_Verbose):
-
- __initialized = False
- # Need to store a reference to sys.exc_info for printing
- # out exceptions when a thread tries to use a global var. during interp.
- # shutdown and thus raises an exception about trying to perform some
- # operation on/with a NoneType
- __exc_info = _sys.exc_info
-
- def __init__(self, group=None, target=None, name=None,
- args=(), kwargs={}, verbose=None):
- assert group is None, "group argument must be None for now"
- _Verbose.__init__(self, verbose)
- self.__target = target
- self.__name = str(name or _newname())
- self.__args = args
- self.__kwargs = kwargs
- self.__daemonic = self._set_daemon()
- self.__started = False
- self.__stopped = False
- self.__block = Condition(Lock())
- self.__initialized = True
- # sys.stderr is not stored in the class like
- # sys.exc_info since it can be changed between instances
- self.__stderr = _sys.stderr
-
- def _set_daemon(self):
- # Overridden in _MainThread and _DummyThread
- return currentThread().isDaemon()
-
- def __repr__(self):
- assert self.__initialized, "Thread.__init__() was not called"
- status = "initial"
- if self.__started:
- status = "started"
- if self.__stopped:
- status = "stopped"
- if self.__daemonic:
- status = status + " daemon"
- return "<%s(%s, %s)>" % (self.__class__.__name__, self.__name, status)
-
- def start(self):
- assert self.__initialized, "Thread.__init__() not called"
- assert not self.__started, "thread already started"
- if __debug__:
- self._note("%s.start(): starting thread", self)
- _active_limbo_lock.acquire()
- _limbo[self] = self
- _active_limbo_lock.release()
- _start_new_thread(self.__bootstrap, ())
- self.__started = True
- _sleep(0.000001) # 1 usec, to let the thread run (Solaris hack)
-
- def run(self):
- if self.__target:
- self.__target(*self.__args, **self.__kwargs)
-
- def __bootstrap(self):
- try:
- self.__started = True
- _active_limbo_lock.acquire()
- _active[_get_ident()] = self
- del _limbo[self]
- _active_limbo_lock.release()
- if __debug__:
- self._note("%s.__bootstrap(): thread started", self)
-
- if _trace_hook:
- self._note("%s.__bootstrap(): registering trace hook", self)
- _sys.settrace(_trace_hook)
- if _profile_hook:
- self._note("%s.__bootstrap(): registering profile hook", self)
- _sys.setprofile(_profile_hook)
-
- try:
- self.run()
- except SystemExit:
- if __debug__:
- self._note("%s.__bootstrap(): raised SystemExit", self)
- except:
- if __debug__:
- self._note("%s.__bootstrap(): unhandled exception", self)
- # If sys.stderr is no more (most likely from interpreter
- # shutdown) use self.__stderr. Otherwise still use sys (as in
- # _sys) in case sys.stderr was redefined since the creation of
- # self.
- if _sys:
- _sys.stderr.write("Exception in thread %s:\n%s\n" %
- (self.getName(), _format_exc()))
- else:
- # Do the best job possible w/o a huge amt. of code to
- # approximate a traceback (code ideas from
- # Lib/traceback.py)
- exc_type, exc_value, exc_tb = self.__exc_info()
- try:
- print>>self.__stderr, (
- "Exception in thread " + self.getName() +
- " (most likely raised during interpreter shutdown):")
- print>>self.__stderr, (
- "Traceback (most recent call last):")
- while exc_tb:
- print>>self.__stderr, (
- ' File "%s", line %s, in %s' %
- (exc_tb.tb_frame.f_code.co_filename,
- exc_tb.tb_lineno,
- exc_tb.tb_frame.f_code.co_name))
- exc_tb = exc_tb.tb_next
- print>>self.__stderr, ("%s: %s" % (exc_type, exc_value))
- # Make sure that exc_tb gets deleted since it is a memory
- # hog; deleting everything else is just for thoroughness
- finally:
- del exc_type, exc_value, exc_tb
- else:
- if __debug__:
- self._note("%s.__bootstrap(): normal return", self)
- finally:
- self.__stop()
- try:
- self.__delete()
- except:
- pass
-
- def __stop(self):
- self.__block.acquire()
- self.__stopped = True
- self.__block.notifyAll()
- self.__block.release()
-
- def __delete(self):
- "Remove current thread from the dict of currently running threads."
-
- # Notes about running with dummy_thread:
- #
- # Must take care to not raise an exception if dummy_thread is being
- # used (and thus this module is being used as an instance of
- # dummy_threading). dummy_thread.get_ident() always returns -1 since
- # there is only one thread if dummy_thread is being used. Thus
- # len(_active) is always <= 1 here, and any Thread instance created
- # overwrites the (if any) thread currently registered in _active.
- #
- # An instance of _MainThread is always created by 'threading'. This
- # gets overwritten the instant an instance of Thread is created; both
- # threads return -1 from dummy_thread.get_ident() and thus have the
- # same key in the dict. So when the _MainThread instance created by
- # 'threading' tries to clean itself up when atexit calls this method
- # it gets a KeyError if another Thread instance was created.
- #
- # This all means that KeyError from trying to delete something from
- # _active if dummy_threading is being used is a red herring. But
- # since it isn't if dummy_threading is *not* being used then don't
- # hide the exception.
-
- _active_limbo_lock.acquire()
- try:
- try:
- del _active[_get_ident()]
- except KeyError:
- if 'dummy_threading' not in _sys.modules:
- raise
- finally:
- _active_limbo_lock.release()
-
- def join(self, timeout=None):
- assert self.__initialized, "Thread.__init__() not called"
- assert self.__started, "cannot join thread before it is started"
- assert self is not currentThread(), "cannot join current thread"
- if __debug__:
- if not self.__stopped:
- self._note("%s.join(): waiting until thread stops", self)
- self.__block.acquire()
- try:
- if timeout is None:
- while not self.__stopped:
- self.__block.wait()
- if __debug__:
- self._note("%s.join(): thread stopped", self)
- else:
- deadline = _time() + timeout
- while not self.__stopped:
- delay = deadline - _time()
- if delay <= 0:
- if __debug__:
- self._note("%s.join(): timed out", self)
- break
- self.__block.wait(delay)
- else:
- if __debug__:
- self._note("%s.join(): thread stopped", self)
- finally:
- self.__block.release()
-
- def getName(self):
- assert self.__initialized, "Thread.__init__() not called"
- return self.__name
-
- def setName(self, name):
- assert self.__initialized, "Thread.__init__() not called"
- self.__name = str(name)
-
- def isAlive(self):
- assert self.__initialized, "Thread.__init__() not called"
- return self.__started and not self.__stopped
-
- def isDaemon(self):
- assert self.__initialized, "Thread.__init__() not called"
- return self.__daemonic
-
- def setDaemon(self, daemonic):
- assert self.__initialized, "Thread.__init__() not called"
- assert not self.__started, "cannot set daemon status of active thread"
- self.__daemonic = daemonic
-
-# The timer class was contributed by Itamar Shtull-Trauring
-
-def Timer(*args, **kwargs):
- return _Timer(*args, **kwargs)
-
-class _Timer(Thread):
- """Call a function after a specified number of seconds:
-
- t = Timer(30.0, f, args=[], kwargs={})
- t.start()
- t.cancel() # stop the timer's action if it's still waiting
- """
-
- def __init__(self, interval, function, args=[], kwargs={}):
- Thread.__init__(self)
- self.interval = interval
- self.function = function
- self.args = args
- self.kwargs = kwargs
- self.finished = Event()
-
- def cancel(self):
- """Stop the timer if it hasn't finished yet"""
- self.finished.set()
-
- def run(self):
- self.finished.wait(self.interval)
- if not self.finished.isSet():
- self.function(*self.args, **self.kwargs)
- self.finished.set()
-
-# Special thread class to represent the main thread
-# This is garbage collected through an exit handler
-
-class _MainThread(Thread):
-
- def __init__(self):
- Thread.__init__(self, name="MainThread")
- self._Thread__started = True
- _active_limbo_lock.acquire()
- _active[_get_ident()] = self
- _active_limbo_lock.release()
- import atexit
- atexit.register(self.__exitfunc)
-
- def _set_daemon(self):
- return False
-
- def __exitfunc(self):
- self._Thread__stop()
- t = _pickSomeNonDaemonThread()
- if t:
- if __debug__:
- self._note("%s: waiting for other threads", self)
- while t:
- t.join()
- t = _pickSomeNonDaemonThread()
- if __debug__:
- self._note("%s: exiting", self)
- self._Thread__delete()
-
-def _pickSomeNonDaemonThread():
- for t in enumerate():
- if not t.isDaemon() and t.isAlive():
- return t
- return None
-
-
-# Dummy thread class to represent threads not started here.
-# These aren't garbage collected when they die,
-# nor can they be waited for.
-# Their purpose is to return *something* from currentThread().
-# They are marked as daemon threads so we won't wait for them
-# when we exit (conform previous semantics).
-
-class _DummyThread(Thread):
-
- def __init__(self):
- Thread.__init__(self, name=_newname("Dummy-%d"))
- self._Thread__started = True
- _active_limbo_lock.acquire()
- _active[_get_ident()] = self
- _active_limbo_lock.release()
-
- def _set_daemon(self):
- return True
-
- def join(self, timeout=None):
- assert False, "cannot join a dummy thread"
-
-
-# Global API functions
-
-def currentThread():
- try:
- return _active[_get_ident()]
- except KeyError:
- ##print "currentThread(): no current thread for", _get_ident()
- return _DummyThread()
-
-def activeCount():
- _active_limbo_lock.acquire()
- count = len(_active) + len(_limbo)
- _active_limbo_lock.release()
- return count
-
-def enumerate():
- _active_limbo_lock.acquire()
- active = _active.values() + _limbo.values()
- _active_limbo_lock.release()
- return active
-
-# Create the main thread object
-
-_MainThread()
-
-# get thread-local implementation, either from the thread
-# module, or from the python fallback
-
-try:
- from thread import _local as local
-except ImportError:
- from _threading_local import local
-
-
-# Self-test code
-
-def _test():
-
- class BoundedQueue(_Verbose):
-
- def __init__(self, limit):
- _Verbose.__init__(self)
- self.mon = RLock()
- self.rc = Condition(self.mon)
- self.wc = Condition(self.mon)
- self.limit = limit
- self.queue = deque()
-
- def put(self, item):
- self.mon.acquire()
- while len(self.queue) >= self.limit:
- self._note("put(%s): queue full", item)
- self.wc.wait()
- self.queue.append(item)
- self._note("put(%s): appended, length now %d",
- item, len(self.queue))
- self.rc.notify()
- self.mon.release()
-
- def get(self):
- self.mon.acquire()
- while not self.queue:
- self._note("get(): queue empty")
- self.rc.wait()
- item = self.queue.popleft()
- self._note("get(): got %s, %d left", item, len(self.queue))
- self.wc.notify()
- self.mon.release()
- return item
-
- class ProducerThread(Thread):
-
- def __init__(self, queue, quota):
- Thread.__init__(self, name="Producer")
- self.queue = queue
- self.quota = quota
-
- def run(self):
- from random import random
- counter = 0
- while counter < self.quota:
- counter = counter + 1
- self.queue.put("%s.%d" % (self.getName(), counter))
- _sleep(random() * 0.00001)
-
-
- class ConsumerThread(Thread):
-
- def __init__(self, queue, count):
- Thread.__init__(self, name="Consumer")
- self.queue = queue
- self.count = count
-
- def run(self):
- while self.count > 0:
- item = self.queue.get()
- print item
- self.count = self.count - 1
-
- NP = 3
- QL = 4
- NI = 5
-
- Q = BoundedQueue(QL)
- P = []
- for i in range(NP):
- t = ProducerThread(Q, NI)
- t.setName("Producer-%d" % (i+1))
- P.append(t)
- C = ConsumerThread(Q, NI*NP)
- for t in P:
- t.start()
- _sleep(0.000001)
- C.start()
- for t in P:
- t.join()
- C.join()
-
-if __name__ == '__main__':
- _test()
diff --git a/gnuradio-core/src/python/gnuradio/gr/hier_block2.py b/gnuradio-core/src/python/gnuradio/gr/hier_block2.py
deleted file mode 100644
index ff39b3e709..0000000000
--- a/gnuradio-core/src/python/gnuradio/gr/hier_block2.py
+++ /dev/null
@@ -1,132 +0,0 @@
-#
-# Copyright 2006,2007 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from gnuradio_core import hier_block2_swig
-
-try:
- import pmt
-except ImportError:
- from gruel import pmt
-
-#
-# This hack forces a 'has-a' relationship to look like an 'is-a' one.
-#
-# It allows Python classes to subclass this one, while passing through
-# method calls to the C++ class shared pointer from SWIG.
-#
-# It also allows us to intercept method calls if needed
-#
-class hier_block2(object):
- """
- Subclass this to create a python hierarchical block.
-
- This is a python wrapper around the C++ hierarchical block implementation.
- Provides convenience functions and allows proper Python subclassing.
- """
-
- def __init__(self, name, input_signature, output_signature):
- """
- Create a hierarchical block with a given name and I/O signatures.
- """
- self._hb = hier_block2_swig(name, input_signature, output_signature)
-
- def __getattr__(self, name):
- """
- Pass-through member requests to the C++ object.
- """
- if not hasattr(self, "_hb"):
- raise RuntimeError("hier_block2: invalid state--did you forget to call gr.hier_block2.__init__ in a derived class?")
- return getattr(self._hb, name)
-
- def connect(self, *points):
- """
- Connect two or more block endpoints. An endpoint is either a (block, port)
- tuple or a block instance. In the latter case, the port number is assumed
- to be zero.
-
- To connect the hierarchical block external inputs or outputs to internal block
- inputs or outputs, use 'self' in the connect call.
-
- If multiple arguments are provided, connect will attempt to wire them in series,
- interpreting the endpoints as inputs or outputs as appropriate.
- """
-
- if len (points) < 1:
- raise ValueError, ("connect requires at least one endpoint; %d provided." % (len (points),))
- else:
- if len(points) == 1:
- self._hb.primitive_connect(points[0].to_basic_block())
- else:
- for i in range (1, len (points)):
- self._connect(points[i-1], points[i])
-
- def _connect(self, src, dst):
- (src_block, src_port) = self._coerce_endpoint(src)
- (dst_block, dst_port) = self._coerce_endpoint(dst)
- self._hb.primitive_connect(src_block.to_basic_block(), src_port,
- dst_block.to_basic_block(), dst_port)
-
- def _coerce_endpoint(self, endp):
- if hasattr(endp, 'to_basic_block'):
- return (endp, 0)
- else:
- if hasattr(endp, "__getitem__") and len(endp) == 2:
- return endp # Assume user put (block, port)
- else:
- raise ValueError("unable to coerce endpoint")
-
- def disconnect(self, *points):
- """
- Disconnect two endpoints in the flowgraph.
-
- To disconnect the hierarchical block external inputs or outputs to internal block
- inputs or outputs, use 'self' in the connect call.
-
- If more than two arguments are provided, they are disconnected successively.
- """
-
- if len (points) < 1:
- raise ValueError, ("disconnect requires at least one endpoint; %d provided." % (len (points),))
- else:
- if len (points) == 1:
- self._hb.primitive_disconnect(points[0].to_basic_block())
- else:
- for i in range (1, len (points)):
- self._disconnect(points[i-1], points[i])
-
- def _disconnect(self, src, dst):
- (src_block, src_port) = self._coerce_endpoint(src)
- (dst_block, dst_port) = self._coerce_endpoint(dst)
- self._hb.primitive_disconnect(src_block.to_basic_block(), src_port,
- dst_block.to_basic_block(), dst_port)
-
- def msg_connect(self, src, srcport, dst, dstport):
- self.primitive_msg_connect(src.to_basic_block(), srcport, dst.to_basic_block(), dstport);
-
- def msg_disconnect(self, src, srcport, dst, dstport):
- self.primitive_msg_disconnect(src.to_basic_block(), srcport, dst.to_basic_block(), dstport);
-
- def message_port_register_hier_in(self, portname):
- self.primitive_message_port_register_hier_in(pmt.intern(portname));
-
- def message_port_register_hier_out(self, portname):
- self.primitive_message_port_register_hier_out(pmt.intern(portname));
-
diff --git a/gnuradio-core/src/python/gnuradio/gr/prefs.py b/gnuradio-core/src/python/gnuradio/gr/prefs.py
deleted file mode 100644
index 25fa8cd6ae..0000000000
--- a/gnuradio-core/src/python/gnuradio/gr/prefs.py
+++ /dev/null
@@ -1,127 +0,0 @@
-#
-# Copyright 2006,2009 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-import gnuradio_core as gsp
-_prefs_base = gsp.gr_prefs
-
-
-import ConfigParser
-import os
-import os.path
-import sys
-import glob
-
-
-def _user_prefs_filename():
- return os.path.expanduser('~/.gnuradio/config.conf')
-
-def _sys_prefs_dirname():
- return gsp.prefsdir()
-
-def _bool(x):
- """
- Try to coerce obj to a True or False
- """
- if isinstance(x, bool):
- return x
- if isinstance(x, (float, int)):
- return bool(x)
- raise TypeError, x
-
-
-class _prefs(_prefs_base):
- """
- Derive our 'real class' from the stubbed out base class that has support
- for SWIG directors. This allows C++ code to magically and transparently
- invoke the methods in this python class.
- """
- def __init__(self):
- _prefs_base.__init__(self)
- self.cp = ConfigParser.RawConfigParser()
- self.__getattr__ = lambda self, name: getattr(self.cp, name)
-
- def _sys_prefs_filenames(self):
- dir = _sys_prefs_dirname()
- try:
- fnames = glob.glob(os.path.join(dir, '*.conf'))
- except (IOError, OSError):
- return []
- fnames.sort()
- return fnames
-
- def _read_files(self):
- filenames = self._sys_prefs_filenames()
- filenames.append(_user_prefs_filename())
- #print "filenames: ", filenames
- self.cp.read(filenames)
-
- # ----------------------------------------------------------------
- # These methods override the C++ virtual methods of the same name
- # ----------------------------------------------------------------
- def has_section(self, section):
- return self.cp.has_section(section)
-
- def has_option(self, section, option):
- return self.cp.has_option(section, option)
-
- def get_string(self, section, option, default_val):
- try:
- return self.cp.get(section, option)
- except:
- return default_val
-
- def get_bool(self, section, option, default_val):
- try:
- return self.cp.getboolean(section, option)
- except:
- return default_val
-
- def get_long(self, section, option, default_val):
- try:
- return self.cp.getint(section, option)
- except:
- return default_val
-
- def get_double(self, section, option, default_val):
- try:
- return self.cp.getfloat(section, option)
- except:
- return default_val
- # ----------------------------------------------------------------
- # End override of C++ virtual methods
- # ----------------------------------------------------------------
-
-
-_prefs_db = _prefs()
-
-# if GR_DONT_LOAD_PREFS is set, don't load them.
-# (make check uses this to avoid interactions.)
-if os.getenv("GR_DONT_LOAD_PREFS", None) is None:
- _prefs_db._read_files()
-
-
-_prefs_base.set_singleton(_prefs_db) # tell C++ what instance to use
-
-def prefs():
- """
- Return the global preference data base
- """
- return _prefs_db
diff --git a/gnuradio-core/src/python/gnuradio/gr/pubsub.py b/gnuradio-core/src/python/gnuradio/gr/pubsub.py
deleted file mode 100644
index 90568418fc..0000000000
--- a/gnuradio-core/src/python/gnuradio/gr/pubsub.py
+++ /dev/null
@@ -1,153 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2008,2009 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-"""
-Abstract GNU Radio publisher/subscriber interface
-
-This is a proof of concept implementation, will likely change significantly.
-"""
-
-class pubsub(dict):
- def __init__(self):
- self._publishers = { }
- self._subscribers = { }
- self._proxies = { }
-
- def __missing__(self, key, value=None):
- dict.__setitem__(self, key, value)
- self._publishers[key] = None
- self._subscribers[key] = []
- self._proxies[key] = None
-
- def __setitem__(self, key, val):
- if not self.has_key(key):
- self.__missing__(key, val)
- elif self._proxies[key] is not None:
- (p, newkey) = self._proxies[key]
- p[newkey] = val
- else:
- dict.__setitem__(self, key, val)
- for sub in self._subscribers[key]:
- # Note this means subscribers will get called in the thread
- # context of the 'set' caller.
- sub(val)
-
- def __getitem__(self, key):
- if not self.has_key(key): self.__missing__(key)
- if self._proxies[key] is not None:
- (p, newkey) = self._proxies[key]
- return p[newkey]
- elif self._publishers[key] is not None:
- return self._publishers[key]()
- else:
- return dict.__getitem__(self, key)
-
- def publish(self, key, publisher):
- if not self.has_key(key): self.__missing__(key)
- if self._proxies[key] is not None:
- (p, newkey) = self._proxies[key]
- p.publish(newkey, publisher)
- else:
- self._publishers[key] = publisher
-
- def subscribe(self, key, subscriber):
- if not self.has_key(key): self.__missing__(key)
- if self._proxies[key] is not None:
- (p, newkey) = self._proxies[key]
- p.subscribe(newkey, subscriber)
- else:
- self._subscribers[key].append(subscriber)
-
- def unpublish(self, key):
- if self._proxies[key] is not None:
- (p, newkey) = self._proxies[key]
- p.unpublish(newkey)
- else:
- self._publishers[key] = None
-
- def unsubscribe(self, key, subscriber):
- if self._proxies[key] is not None:
- (p, newkey) = self._proxies[key]
- p.unsubscribe(newkey, subscriber)
- else:
- self._subscribers[key].remove(subscriber)
-
- def proxy(self, key, p, newkey=None):
- if not self.has_key(key): self.__missing__(key)
- if newkey is None: newkey = key
- self._proxies[key] = (p, newkey)
-
- def unproxy(self, key):
- self._proxies[key] = None
-
-# Test code
-if __name__ == "__main__":
- import sys
- o = pubsub()
-
- # Non-existent key gets auto-created with None value
- print "Auto-created key 'foo' value:", o['foo']
-
- # Add some subscribers
- # First is a bare function
- def print_len(x):
- print "len=%i" % (len(x), )
- o.subscribe('foo', print_len)
-
- # The second is a class member function
- class subber(object):
- def __init__(self, param):
- self._param = param
- def printer(self, x):
- print self._param, `x`
- s = subber('param')
- o.subscribe('foo', s.printer)
-
- # The third is a lambda function
- o.subscribe('foo', lambda x: sys.stdout.write('val='+`x`+'\n'))
-
- # Update key 'foo', will notify subscribers
- print "Updating 'foo' with three subscribers:"
- o['foo'] = 'bar';
-
- # Remove first subscriber
- o.unsubscribe('foo', print_len)
-
- # Update now will only trigger second and third subscriber
- print "Updating 'foo' after removing a subscriber:"
- o['foo'] = 'bar2';
-
- # Publish a key as a function, in this case, a lambda function
- o.publish('baz', lambda : 42)
- print "Published value of 'baz':", o['baz']
-
- # Unpublish the key
- o.unpublish('baz')
-
- # This will return None, as there is no publisher
- print "Value of 'baz' with no publisher:", o['baz']
-
- # Set 'baz' key, it gets cached
- o['baz'] = 'bazzz'
-
- # Now will return cached value, since no provider
- print "Cached value of 'baz' after being set:", o['baz']
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_feval.py b/gnuradio-core/src/python/gnuradio/gr/qa_feval.py
deleted file mode 100755
index 9018e12f36..0000000000
--- a/gnuradio-core/src/python/gnuradio/gr/qa_feval.py
+++ /dev/null
@@ -1,110 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2006,2007,2010 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from gnuradio import gr, gr_unittest
-
-class my_add2_dd(gr.feval_dd):
- def eval(self, x):
- return x + 2
-
-class my_add2_ll(gr.feval_ll):
- def eval(self, x):
- return x + 2
-
-class my_add2_cc(gr.feval_cc):
- def eval(self, x):
- return x + (2 - 2j)
-
-class my_feval(gr.feval):
- def __init__(self):
- gr.feval.__init__(self)
- self.fired = False
- def eval(self):
- self.fired = True
-
-class test_feval(gr_unittest.TestCase):
-
- def test_dd_1(self):
- f = my_add2_dd()
- src_data = (0.0, 1.0, 2.0, 3.0, 4.0)
- expected_result = (2.0, 3.0, 4.0, 5.0, 6.0)
- # this is all in python...
- actual_result = tuple([f.eval(x) for x in src_data])
- self.assertEqual(expected_result, actual_result)
-
- def test_dd_2(self):
- f = my_add2_dd()
- src_data = (0.0, 1.0, 2.0, 3.0, 4.0)
- expected_result = (2.0, 3.0, 4.0, 5.0, 6.0)
- # this is python -> C++ -> python and back again...
- actual_result = tuple([gr.feval_dd_example(f, x) for x in src_data])
- self.assertEqual(expected_result, actual_result)
-
-
- def test_ll_1(self):
- f = my_add2_ll()
- src_data = (0, 1, 2, 3, 4)
- expected_result = (2, 3, 4, 5, 6)
- # this is all in python...
- actual_result = tuple([f.eval(x) for x in src_data])
- self.assertEqual(expected_result, actual_result)
-
- def test_ll_2(self):
- f = my_add2_ll()
- src_data = (0, 1, 2, 3, 4)
- expected_result = (2, 3, 4, 5, 6)
- # this is python -> C++ -> python and back again...
- actual_result = tuple([gr.feval_ll_example(f, x) for x in src_data])
- self.assertEqual(expected_result, actual_result)
-
-
- def test_cc_1(self):
- f = my_add2_cc()
- src_data = (0+1j, 2+3j, 4+5j, 6+7j)
- expected_result = (2-1j, 4+1j, 6+3j, 8+5j)
- # this is all in python...
- actual_result = tuple([f.eval(x) for x in src_data])
- self.assertEqual(expected_result, actual_result)
-
- def test_cc_2(self):
- f = my_add2_cc()
- src_data = (0+1j, 2+3j, 4+5j, 6+7j)
- expected_result = (2-1j, 4+1j, 6+3j, 8+5j)
- # this is python -> C++ -> python and back again...
- actual_result = tuple([gr.feval_cc_example(f, x) for x in src_data])
- self.assertEqual(expected_result, actual_result)
-
- def test_void_1(self):
- # this is all in python
- f = my_feval()
- f.eval()
- self.assertEqual(True, f.fired)
-
- def test_void_2(self):
- # this is python -> C++ -> python and back again
- f = my_feval()
- gr.feval_example(f)
- self.assertEqual(True, f.fired)
-
-
-if __name__ == '__main__':
- gr_unittest.run(test_feval, "test_feval.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_kludged_imports.py b/gnuradio-core/src/python/gnuradio/gr/qa_kludged_imports.py
deleted file mode 100755
index f80188c9fc..0000000000
--- a/gnuradio-core/src/python/gnuradio/gr/qa_kludged_imports.py
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2005,2008,2010 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from gnuradio import gr, gr_unittest
-
-class test_kludged_imports (gr_unittest.TestCase):
-
- def setUp(self):
- pass
-
- def tearDown(self):
- pass
-
- def test_gru_import(self):
- # make sure that this somewhat magic import works
- from gnuradio import gru
-
-
-if __name__ == '__main__':
- gr_unittest.run(test_kludged_imports, "test_kludged_imports.xml")
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_tag_utils.py b/gnuradio-core/src/python/gnuradio/gr/qa_tag_utils.py
deleted file mode 100755
index de1b5aa002..0000000000
--- a/gnuradio-core/src/python/gnuradio/gr/qa_tag_utils.py
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2007,2010 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from gnuradio import gr, gr_unittest
-import tag_utils
-
-try:
- import pmt_swig as pmt
-except ImportError:
- import pmt
-
-class test_tag_utils (gr_unittest.TestCase):
-
- def setUp (self):
- self.tb = gr.top_block ()
-
-
- def tearDown (self):
- self.tb = None
-
- def test_001(self):
- t = gr.gr_tag_t()
- t.offset = 10
- t.key = pmt.string_to_symbol('key')
- t.value = pmt.from_long(23)
- t.srcid = pmt.from_bool(False)
- pt = tag_utils.tag_to_python(t)
- self.assertEqual(pt.key, 'key')
- self.assertEqual(pt.value, 23)
- self.assertEqual(pt.offset, 10)
-
-
-if __name__ == '__main__':
- print 'hi'
- gr_unittest.run(test_tag_utils, "test_tag_utils.xml")
-
diff --git a/gnuradio-core/src/python/gnuradio/gr/tag_utils.py b/gnuradio-core/src/python/gnuradio/gr/tag_utils.py
deleted file mode 100644
index 923718fc98..0000000000
--- a/gnuradio-core/src/python/gnuradio/gr/tag_utils.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#
-# Copyright 2003-2012 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-""" Conversion tools between stream tags and Python objects """
-
-try: import pmt
-except: from gruel import pmt
-
-from gnuradio_core import gr_tag_t
-
-class PythonTag(object):
- " Python container for tags "
- def __init__(self):
- self.offset = None
- self.key = None
- self.value = None
- self.srcid = None
-
-def tag_to_python(tag):
- """ Convert a stream tag to a Python-readable object """
- newtag = PythonTag()
- newtag.offset = tag.offset
- newtag.key = pmt.to_python(tag.key)
- newtag.value = pmt.to_python(tag.value)
- newtag.srcid = pmt.to_python(tag.srcid)
- return newtag
-
-def tag_to_pmt(tag):
- """ Convert a Python-readable object to a stream tag """
- newtag = gr_tag_t()
- newtag.offset = tag.offset
- newtag.key = pmt.to_python(tag.key)
- newtag.value = pmt.from_python(tag.value)
- newtag.srcid = pmt.from_python(tag.srcid)
- return newtag
-
-
diff --git a/gnuradio-core/src/python/gnuradio/gr/top_block.py b/gnuradio-core/src/python/gnuradio/gr/top_block.py
deleted file mode 100644
index 947e46bc55..0000000000
--- a/gnuradio-core/src/python/gnuradio/gr/top_block.py
+++ /dev/null
@@ -1,171 +0,0 @@
-#
-# Copyright 2007 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from gnuradio_core import top_block_swig, \
- top_block_wait_unlocked, top_block_run_unlocked
-
-#import gnuradio.gr.gr_threading as _threading
-import gr_threading as _threading
-
-
-#
-# There is no problem that can't be solved with an additional
-# level of indirection...
-#
-# This kludge allows ^C to interrupt top_block.run and top_block.wait
-#
-# The problem that we are working around is that Python only services
-# signals (e.g., KeyboardInterrupt) in its main thread. If the main
-# thread is blocked in our C++ version of wait, even though Python's
-# SIGINT handler fires, and even though there may be other python
-# threads running, no one will know. Thus instead of directly waiting
-# in the thread that calls wait (which is likely to be the Python main
-# thread), we create a separate thread that does the blocking wait,
-# and then use the thread that called wait to do a slow poll of an
-# event queue. That thread, which is executing "wait" below is
-# interruptable, and if it sees a KeyboardInterrupt, executes a stop
-# on the top_block, then goes back to waiting for it to complete.
-# This ensures that the unlocked wait that was in progress (in the
-# _top_block_waiter thread) can complete, release its mutex and back
-# out. If we don't do that, we are never able to clean up, and nasty
-# things occur like leaving the USRP transmitter sending a carrier.
-#
-# See also top_block.wait (below), which uses this class to implement
-# the interruptable wait.
-#
-class _top_block_waiter(_threading.Thread):
- def __init__(self, tb):
- _threading.Thread.__init__(self)
- self.setDaemon(1)
- self.tb = tb
- self.event = _threading.Event()
- self.start()
-
- def run(self):
- top_block_wait_unlocked(self.tb)
- self.event.set()
-
- def wait(self):
- try:
- while not self.event.isSet():
- self.event.wait(0.100)
- except KeyboardInterrupt:
- self.tb.stop()
- self.wait()
-
-
-#
-# This hack forces a 'has-a' relationship to look like an 'is-a' one.
-#
-# It allows Python classes to subclass this one, while passing through
-# method calls to the C++ class shared pointer from SWIG.
-#
-# It also allows us to intercept method calls if needed.
-#
-# This allows the 'run_locked' methods, which are defined in gr_top_block.i,
-# to release the Python global interpreter lock before calling the actual
-# method in gr_top_block
-#
-class top_block(object):
- """
- Top-level hierarchical block representing a flow-graph.
-
- This is a python wrapper around the C++ implementation to allow
- python subclassing.
- """
- def __init__(self, name="top_block"):
- self._tb = top_block_swig(name)
-
- def __getattr__(self, name):
- if not hasattr(self, "_tb"):
- raise RuntimeError("top_block: invalid state--did you forget to call gr.top_block.__init__ in a derived class?")
- return getattr(self._tb, name)
-
- def start(self, max_noutput_items=10000000):
- self._tb.start(max_noutput_items)
-
- def stop(self):
- self._tb.stop()
-
- def run(self, max_noutput_items=10000000):
- self.start(max_noutput_items)
- self.wait()
-
- def wait(self):
- _top_block_waiter(self._tb).wait()
-
-
- # FIXME: these are duplicated from hier_block2.py; they should really be implemented
- # in the original C++ class (gr_hier_block2), then they would all be inherited here
-
- def connect(self, *points):
- '''connect requires one or more arguments that can be coerced to endpoints.
- If more than two arguments are provided, they are connected together successively.
- '''
- if len (points) < 1:
- raise ValueError, ("connect requires at least one endpoint; %d provided." % (len (points),))
- else:
- if len(points) == 1:
- self._tb.primitive_connect(points[0].to_basic_block())
- else:
- for i in range (1, len (points)):
- self._connect(points[i-1], points[i])
-
- def msg_connect(self, src, srcport, dst, dstport):
- self.primitive_msg_connect(src.to_basic_block(), srcport, dst.to_basic_block(), dstport);
-
- def msg_disconnect(self, src, srcport, dst, dstport):
- self.primitive_msg_disconnect(src.to_basic_block(), srcport, dst.to_basic_block(), dstport);
-
- def _connect(self, src, dst):
- (src_block, src_port) = self._coerce_endpoint(src)
- (dst_block, dst_port) = self._coerce_endpoint(dst)
- self._tb.primitive_connect(src_block.to_basic_block(), src_port,
- dst_block.to_basic_block(), dst_port)
-
- def _coerce_endpoint(self, endp):
- if hasattr(endp, 'to_basic_block'):
- return (endp, 0)
- else:
- if hasattr(endp, "__getitem__") and len(endp) == 2:
- return endp # Assume user put (block, port)
- else:
- raise ValueError("unable to coerce endpoint")
-
- def disconnect(self, *points):
- '''disconnect requires one or more arguments that can be coerced to endpoints.
- If more than two arguments are provided, they are disconnected successively.
- '''
- if len (points) < 1:
- raise ValueError, ("disconnect requires at least one endpoint; %d provided." % (len (points),))
- else:
- if len(points) == 1:
- self._tb.primitive_disconnect(points[0].to_basic_block())
- else:
- for i in range (1, len (points)):
- self._disconnect(points[i-1], points[i])
-
- def _disconnect(self, src, dst):
- (src_block, src_port) = self._coerce_endpoint(src)
- (dst_block, dst_port) = self._coerce_endpoint(dst)
- self._tb.primitive_disconnect(src_block.to_basic_block(), src_port,
- dst_block.to_basic_block(), dst_port)
-
diff --git a/gnuradio-core/src/python/gnuradio/gr_unittest.py b/gnuradio-core/src/python/gnuradio/gr_unittest.py
deleted file mode 100755
index c729566e88..0000000000
--- a/gnuradio-core/src/python/gnuradio/gr_unittest.py
+++ /dev/null
@@ -1,170 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2004,2010 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-"""
-GNU radio specific extension of unittest.
-"""
-
-import unittest
-import gr_xmlrunner
-import sys, os, stat
-
-class TestCase(unittest.TestCase):
- """A subclass of unittest.TestCase that adds additional assertions
-
- Adds new methods assertComplexAlmostEqual,
- assertComplexTuplesAlmostEqual and assertFloatTuplesAlmostEqual
- """
-
- def assertComplexAlmostEqual (self, first, second, places=7, msg=None):
- """Fail if the two complex objects are unequal as determined by their
- difference rounded to the given number of decimal places
- (default 7) and comparing to zero.
-
- Note that decimal places (from zero) is usually not the same
- as significant digits (measured from the most signficant digit).
- """
- if round(second.real-first.real, places) != 0:
- raise self.failureException, \
- (msg or '%s != %s within %s places' % (`first`, `second`, `places` ))
- if round(second.imag-first.imag, places) != 0:
- raise self.failureException, \
- (msg or '%s != %s within %s places' % (`first`, `second`, `places` ))
-
- def assertComplexAlmostEqual2 (self, ref, x, abs_eps=1e-12, rel_eps=1e-6, msg=None):
- """
- Fail if the two complex objects are unequal as determined by...
- """
- if abs(ref - x) < abs_eps:
- return
-
- if abs(ref) > abs_eps:
- if abs(ref-x)/abs(ref) > rel_eps:
- raise self.failureException, \
- (msg or '%s != %s rel_error = %s rel_limit = %s' % (
- `ref`, `x`, abs(ref-x)/abs(ref), `rel_eps` ))
- else:
- raise self.failureException, \
- (msg or '%s != %s rel_error = %s rel_limit = %s' % (
- `ref`, `x`, abs(ref-x)/abs(ref), `rel_eps` ))
-
-
-
- def assertComplexTuplesAlmostEqual (self, a, b, places=7, msg=None):
- self.assertEqual (len(a), len(b))
- for i in xrange (len(a)):
- self.assertComplexAlmostEqual (a[i], b[i], places, msg)
-
- def assertComplexTuplesAlmostEqual2 (self, ref, x,
- abs_eps=1e-12, rel_eps=1e-6, msg=None):
- self.assertEqual (len(ref), len(x))
- for i in xrange (len(ref)):
- try:
- self.assertComplexAlmostEqual2 (ref[i], x[i], abs_eps, rel_eps, msg)
- except self.failureException, e:
- #sys.stderr.write("index = %d " % (i,))
- #sys.stderr.write("%s\n" % (e,))
- raise
-
- def assertFloatTuplesAlmostEqual (self, a, b, places=7, msg=None):
- self.assertEqual (len(a), len(b))
- for i in xrange (len(a)):
- self.assertAlmostEqual (a[i], b[i], places, msg)
-
-
- def assertFloatTuplesAlmostEqual2 (self, ref, x,
- abs_eps=1e-12, rel_eps=1e-6, msg=None):
- self.assertEqual (len(ref), len(x))
- for i in xrange (len(ref)):
- try:
- self.assertComplexAlmostEqual2 (ref[i], x[i], abs_eps, rel_eps, msg)
- except self.failureException, e:
- #sys.stderr.write("index = %d " % (i,))
- #sys.stderr.write("%s\n" % (e,))
- raise
-
-
-TestResult = unittest.TestResult
-TestSuite = unittest.TestSuite
-FunctionTestCase = unittest.FunctionTestCase
-TestLoader = unittest.TestLoader
-TextTestRunner = unittest.TextTestRunner
-TestProgram = unittest.TestProgram
-main = TestProgram
-
-def run(PUT, filename=None):
- '''
- Runs the unittest on a TestCase and produces an optional XML report
- PUT: the program under test and should be a gr_unittest.TestCase
- filename: an optional filename to save the XML report of the tests
- this will live in ./.unittests/python
- '''
-
- # Run this is given a file name
- if(filename is not None):
- basepath = "./.unittests"
- path = basepath + "/python"
-
- if not os.path.exists(basepath):
- os.makedirs(basepath, 0750)
-
- xmlrunner = None
- # only proceed if .unittests is writable
- st = os.stat(basepath)[stat.ST_MODE]
- if(st & stat.S_IWUSR > 0):
- # Test if path exists; if not, build it
- if not os.path.exists(path):
- os.makedirs(path, 0750)
-
- # Just for safety: make sure we can write here, too
- st = os.stat(path)[stat.ST_MODE]
- if(st & stat.S_IWUSR > 0):
- # Create an XML runner to filename
- fout = file(path+"/"+filename, "w")
- xmlrunner = gr_xmlrunner.XMLTestRunner(fout)
-
- txtrunner = TextTestRunner(verbosity=1)
-
- # Run the test; runner also creates XML output file
- # FIXME: make xmlrunner output to screen so we don't have to do run and main
- suite = TestLoader().loadTestsFromTestCase(PUT)
-
- # use the xmlrunner if we can write the the directory
- if(xmlrunner is not None):
- xmlrunner.run(suite)
-
- main()
-
- # This will run and fail make check if problem
- # but does not output to screen.
- #main(testRunner = xmlrunner)
-
- else:
- # If no filename is given, just run the test
- main()
-
-
-##############################################################################
-# Executing this module from the command line
-##############################################################################
-
-if __name__ == "__main__":
- main(module=None)
diff --git a/gnuradio-core/src/python/gnuradio/gr_xmlrunner.py b/gnuradio-core/src/python/gnuradio/gr_xmlrunner.py
deleted file mode 100644
index 31298197ff..0000000000
--- a/gnuradio-core/src/python/gnuradio/gr_xmlrunner.py
+++ /dev/null
@@ -1,387 +0,0 @@
-"""
-XML Test Runner for PyUnit
-"""
-
-# Written by Sebastian Rittau <srittau@jroger.in-berlin.de> and placed in
-# the Public Domain. With contributions by Paolo Borelli and others.
-# Added to GNU Radio Oct. 3, 2010
-
-__version__ = "0.1"
-
-import os.path
-import re
-import sys
-import time
-import traceback
-import unittest
-from xml.sax.saxutils import escape
-
-try:
- from StringIO import StringIO
-except ImportError:
- from io import StringIO
-
-
-class _TestInfo(object):
-
- """Information about a particular test.
-
- Used by _XMLTestResult.
-
- """
-
- def __init__(self, test, time):
- (self._class, self._method) = test.id().rsplit(".", 1)
- self._time = time
- self._error = None
- self._failure = None
-
- @staticmethod
- def create_success(test, time):
- """Create a _TestInfo instance for a successful test."""
- return _TestInfo(test, time)
-
- @staticmethod
- def create_failure(test, time, failure):
- """Create a _TestInfo instance for a failed test."""
- info = _TestInfo(test, time)
- info._failure = failure
- return info
-
- @staticmethod
- def create_error(test, time, error):
- """Create a _TestInfo instance for an erroneous test."""
- info = _TestInfo(test, time)
- info._error = error
- return info
-
- def print_report(self, stream):
- """Print information about this test case in XML format to the
- supplied stream.
-
- """
- stream.write(' <testcase classname="%(class)s" name="%(method)s" time="%(time).4f">' % \
- {
- "class": self._class,
- "method": self._method,
- "time": self._time,
- })
- if self._failure is not None:
- self._print_error(stream, 'failure', self._failure)
- if self._error is not None:
- self._print_error(stream, 'error', self._error)
- stream.write('</testcase>\n')
-
- def _print_error(self, stream, tagname, error):
- """Print information from a failure or error to the supplied stream."""
- text = escape(str(error[1]))
- stream.write('\n')
- stream.write(' <%s type="%s">%s\n' \
- % (tagname, _clsname(error[0]), text))
- tb_stream = StringIO()
- traceback.print_tb(error[2], None, tb_stream)
- stream.write(escape(tb_stream.getvalue()))
- stream.write(' </%s>\n' % tagname)
- stream.write(' ')
-
-
-def _clsname(cls):
- return cls.__module__ + "." + cls.__name__
-
-
-class _XMLTestResult(unittest.TestResult):
-
- """A test result class that stores result as XML.
-
- Used by XMLTestRunner.
-
- """
-
- def __init__(self, classname):
- unittest.TestResult.__init__(self)
- self._test_name = classname
- self._start_time = None
- self._tests = []
- self._error = None
- self._failure = None
-
- def startTest(self, test):
- unittest.TestResult.startTest(self, test)
- self._error = None
- self._failure = None
- self._start_time = time.time()
-
- def stopTest(self, test):
- time_taken = time.time() - self._start_time
- unittest.TestResult.stopTest(self, test)
- if self._error:
- info = _TestInfo.create_error(test, time_taken, self._error)
- elif self._failure:
- info = _TestInfo.create_failure(test, time_taken, self._failure)
- else:
- info = _TestInfo.create_success(test, time_taken)
- self._tests.append(info)
-
- def addError(self, test, err):
- unittest.TestResult.addError(self, test, err)
- self._error = err
-
- def addFailure(self, test, err):
- unittest.TestResult.addFailure(self, test, err)
- self._failure = err
-
- def print_report(self, stream, time_taken, out, err):
- """Prints the XML report to the supplied stream.
-
- The time the tests took to perform as well as the captured standard
- output and standard error streams must be passed in.a
-
- """
- stream.write('<testsuite errors="%(e)d" failures="%(f)d" ' % \
- { "e": len(self.errors), "f": len(self.failures) })
- stream.write('name="%(n)s" tests="%(t)d" time="%(time).3f">\n' % \
- {
- "n": self._test_name,
- "t": self.testsRun,
- "time": time_taken,
- })
- for info in self._tests:
- info.print_report(stream)
- stream.write(' <system-out><![CDATA[%s]]></system-out>\n' % out)
- stream.write(' <system-err><![CDATA[%s]]></system-err>\n' % err)
- stream.write('</testsuite>\n')
-
-
-class XMLTestRunner(object):
-
- """A test runner that stores results in XML format compatible with JUnit.
-
- XMLTestRunner(stream=None) -> XML test runner
-
- The XML file is written to the supplied stream. If stream is None, the
- results are stored in a file called TEST-<module>.<class>.xml in the
- current working directory (if not overridden with the path property),
- where <module> and <class> are the module and class name of the test class.
-
- """
-
- def __init__(self, stream=None):
- self._stream = stream
- self._path = "."
-
- def run(self, test):
- """Run the given test case or test suite."""
- class_ = test.__class__
- classname = class_.__module__ + "." + class_.__name__
- if self._stream == None:
- filename = "TEST-%s.xml" % classname
- stream = file(os.path.join(self._path, filename), "w")
- stream.write('<?xml version="1.0" encoding="utf-8"?>\n')
- else:
- stream = self._stream
-
- result = _XMLTestResult(classname)
- start_time = time.time()
-
- fss = _fake_std_streams()
- fss.__enter__()
- try:
- test(result)
- try:
- out_s = sys.stdout.getvalue()
- except AttributeError:
- out_s = ""
- try:
- err_s = sys.stderr.getvalue()
- except AttributeError:
- err_s = ""
- finally:
- fss.__exit__(None, None, None)
-
- time_taken = time.time() - start_time
- result.print_report(stream, time_taken, out_s, err_s)
- if self._stream is None:
- stream.close()
-
- return result
-
- def _set_path(self, path):
- self._path = path
-
- path = property(lambda self: self._path, _set_path, None,
- """The path where the XML files are stored.
-
- This property is ignored when the XML file is written to a file
- stream.""")
-
-
-class _fake_std_streams(object):
-
- def __enter__(self):
- self._orig_stdout = sys.stdout
- self._orig_stderr = sys.stderr
- #sys.stdout = StringIO()
- #sys.stderr = StringIO()
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- sys.stdout = self._orig_stdout
- sys.stderr = self._orig_stderr
-
-
-class XMLTestRunnerTest(unittest.TestCase):
-
- def setUp(self):
- self._stream = StringIO()
-
- def _try_test_run(self, test_class, expected):
-
- """Run the test suite against the supplied test class and compare the
- XML result against the expected XML string. Fail if the expected
- string doesn't match the actual string. All time attributes in the
- expected string should have the value "0.000". All error and failure
- messages are reduced to "Foobar".
-
- """
-
- runner = XMLTestRunner(self._stream)
- runner.run(unittest.makeSuite(test_class))
-
- got = self._stream.getvalue()
- # Replace all time="X.YYY" attributes by time="0.000" to enable a
- # simple string comparison.
- got = re.sub(r'time="\d+\.\d+"', 'time="0.000"', got)
- # Likewise, replace all failure and error messages by a simple "Foobar"
- # string.
- got = re.sub(r'(?s)<failure (.*?)>.*?</failure>', r'<failure \1>Foobar</failure>', got)
- got = re.sub(r'(?s)<error (.*?)>.*?</error>', r'<error \1>Foobar</error>', got)
- # And finally Python 3 compatibility.
- got = got.replace('type="builtins.', 'type="exceptions.')
-
- self.assertEqual(expected, got)
-
- def test_no_tests(self):
- """Regression test: Check whether a test run without any tests
- matches a previous run.
-
- """
- class TestTest(unittest.TestCase):
- pass
- self._try_test_run(TestTest, """<testsuite errors="0" failures="0" name="unittest.TestSuite" tests="0" time="0.000">
- <system-out><![CDATA[]]></system-out>
- <system-err><![CDATA[]]></system-err>
-</testsuite>
-""")
-
- def test_success(self):
- """Regression test: Check whether a test run with a successful test
- matches a previous run.
-
- """
- class TestTest(unittest.TestCase):
- def test_foo(self):
- pass
- self._try_test_run(TestTest, """<testsuite errors="0" failures="0" name="unittest.TestSuite" tests="1" time="0.000">
- <testcase classname="__main__.TestTest" name="test_foo" time="0.000"></testcase>
- <system-out><![CDATA[]]></system-out>
- <system-err><![CDATA[]]></system-err>
-</testsuite>
-""")
-
- def test_failure(self):
- """Regression test: Check whether a test run with a failing test
- matches a previous run.
-
- """
- class TestTest(unittest.TestCase):
- def test_foo(self):
- self.assert_(False)
- self._try_test_run(TestTest, """<testsuite errors="0" failures="1" name="unittest.TestSuite" tests="1" time="0.000">
- <testcase classname="__main__.TestTest" name="test_foo" time="0.000">
- <failure type="exceptions.AssertionError">Foobar</failure>
- </testcase>
- <system-out><![CDATA[]]></system-out>
- <system-err><![CDATA[]]></system-err>
-</testsuite>
-""")
-
- def test_error(self):
- """Regression test: Check whether a test run with a erroneous test
- matches a previous run.
-
- """
- class TestTest(unittest.TestCase):
- def test_foo(self):
- raise IndexError()
- self._try_test_run(TestTest, """<testsuite errors="1" failures="0" name="unittest.TestSuite" tests="1" time="0.000">
- <testcase classname="__main__.TestTest" name="test_foo" time="0.000">
- <error type="exceptions.IndexError">Foobar</error>
- </testcase>
- <system-out><![CDATA[]]></system-out>
- <system-err><![CDATA[]]></system-err>
-</testsuite>
-""")
-
- def test_stdout_capture(self):
- """Regression test: Check whether a test run with output to stdout
- matches a previous run.
-
- """
- class TestTest(unittest.TestCase):
- def test_foo(self):
- sys.stdout.write("Test\n")
- self._try_test_run(TestTest, """<testsuite errors="0" failures="0" name="unittest.TestSuite" tests="1" time="0.000">
- <testcase classname="__main__.TestTest" name="test_foo" time="0.000"></testcase>
- <system-out><![CDATA[Test
-]]></system-out>
- <system-err><![CDATA[]]></system-err>
-</testsuite>
-""")
-
- def test_stderr_capture(self):
- """Regression test: Check whether a test run with output to stderr
- matches a previous run.
-
- """
- class TestTest(unittest.TestCase):
- def test_foo(self):
- sys.stderr.write("Test\n")
- self._try_test_run(TestTest, """<testsuite errors="0" failures="0" name="unittest.TestSuite" tests="1" time="0.000">
- <testcase classname="__main__.TestTest" name="test_foo" time="0.000"></testcase>
- <system-out><![CDATA[]]></system-out>
- <system-err><![CDATA[Test
-]]></system-err>
-</testsuite>
-""")
-
- class NullStream(object):
- """A file-like object that discards everything written to it."""
- def write(self, buffer):
- pass
-
- def test_unittests_changing_stdout(self):
- """Check whether the XMLTestRunner recovers gracefully from unit tests
- that change stdout, but don't change it back properly.
-
- """
- class TestTest(unittest.TestCase):
- def test_foo(self):
- sys.stdout = XMLTestRunnerTest.NullStream()
-
- runner = XMLTestRunner(self._stream)
- runner.run(unittest.makeSuite(TestTest))
-
- def test_unittests_changing_stderr(self):
- """Check whether the XMLTestRunner recovers gracefully from unit tests
- that change stderr, but don't change it back properly.
-
- """
- class TestTest(unittest.TestCase):
- def test_foo(self):
- sys.stderr = XMLTestRunnerTest.NullStream()
-
- runner = XMLTestRunner(self._stream)
- runner.run(unittest.makeSuite(TestTest))
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/gnuradio-core/src/python/gnuradio/gru/CMakeLists.txt b/gnuradio-core/src/python/gnuradio/gru/CMakeLists.txt
deleted file mode 100644
index 1c50989d96..0000000000
--- a/gnuradio-core/src/python/gnuradio/gru/CMakeLists.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright 2010-2011 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-
-include(GrPython)
-
-GR_PYTHON_INSTALL(
- FILES __init__.py
- DESTINATION ${GR_PYTHON_DIR}/gnuradio/gru
- COMPONENT "core_python"
-)
diff --git a/gnuradio-core/src/python/gnuradio/gru/__init__.py b/gnuradio-core/src/python/gnuradio/gru/__init__.py
deleted file mode 100644
index c24439ff54..0000000000
--- a/gnuradio-core/src/python/gnuradio/gru/__init__.py
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-# Copyright 2005 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-import glob
-import os.path
-
-# Semi-hideous kludge to import everything in the gruimpl directory
-# into the gnuradio.gru namespace. This keeps us from having to remember
-# to manually update this file.
-
-for p in __path__:
- filenames = glob.glob (os.path.join (p, "..", "gruimpl", "*.py"))
- for f in filenames:
- f = os.path.basename(f).lower()
- f = f[:-3]
- if f == '__init__':
- continue
- # print f
- exec "from gnuradio.gruimpl.%s import *" % (f,)
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/CMakeLists.txt b/gnuradio-core/src/python/gnuradio/gruimpl/CMakeLists.txt
deleted file mode 100644
index d77da24073..0000000000
--- a/gnuradio-core/src/python/gnuradio/gruimpl/CMakeLists.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright 2010-2011 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-
-include(GrPython)
-
-GR_PYTHON_INSTALL(FILES
- __init__.py
- freqz.py
- gnuplot_freqz.py
- hexint.py
- listmisc.py
- mathmisc.py
- msgq_runner.py
- os_read_exactly.py
- seq_with_cursor.py
- socket_stuff.py
- daemon.py
- DESTINATION ${GR_PYTHON_DIR}/gnuradio/gruimpl
- COMPONENT "core_python"
-)
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/__init__.py b/gnuradio-core/src/python/gnuradio/gruimpl/__init__.py
deleted file mode 100644
index a4917cf64c..0000000000
--- a/gnuradio-core/src/python/gnuradio/gruimpl/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-# make this a package
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/daemon.py b/gnuradio-core/src/python/gnuradio/gruimpl/daemon.py
deleted file mode 100644
index e04702152d..0000000000
--- a/gnuradio-core/src/python/gnuradio/gruimpl/daemon.py
+++ /dev/null
@@ -1,102 +0,0 @@
-#
-# Copyright 2008 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-import os, sys, signal
-
-# Turn application into a background daemon process.
-#
-# When this function returns:
-#
-# 1) The calling process is disconnected from its controlling terminal
-# and will not exit when the controlling session exits
-# 2) If a pidfile name is provided, it is created and the new pid is
-# written into it.
-# 3) If a logfile name is provided, it is opened and stdout/stderr are
-# redirected to it.
-# 4) The process current working directory is changed to '/' to avoid
-# pinning any filesystem mounts.
-# 5) The process umask is set to 0111.
-#
-# The return value is the new pid.
-#
-# To create GNU Radio applications that operate as daemons, add a call to this
-# function after all initialization but just before calling gr.top_block.run()
-# or .start().
-#
-# Daemonized GNU Radio applications may be stopped by sending them a
-# SIGINT, SIGKILL, or SIGTERM, e.g., using 'kill pid' from the command line.
-#
-# If your application uses gr.top_block.run(), the flowgraph will be stopped
-# and the function will return. You should allow your daemon program to exit
-# at this point.
-#
-# If your application uses gr.top_block.start(), you are responsible for hooking
-# the Python signal handler (see 'signal' module) and calling gr.top_block.stop()
-# on your top block, and otherwise causing your daemon process to exit.
-#
-
-def daemonize(pidfile=None, logfile=None):
- # fork() into background
- try:
- pid = os.fork()
- except OSError, e:
- raise Exception, "%s [%d]" % (e.strerror, e.errno)
-
- if pid == 0: # First child of first fork()
- # Become session leader of new session
- os.setsid()
-
- # fork() into background again
- try:
- pid = os.fork()
- except OSError, e:
- raise Exception, "%s [%d]" % (e.strerror, e.errno)
-
- if pid != 0:
- os._exit(0) # Second child of second fork()
-
- else: # Second child of first fork()
- os._exit(0)
-
- os.umask(0111)
-
- # Write pid
- pid = os.getpid()
- if pidfile is not None:
- open(pidfile, 'w').write('%d\n'%pid)
-
- # Redirect streams
- if logfile is not None:
- lf = open(logfile, 'a+')
- sys.stdout = lf
- sys.stderr = lf
-
- # Prevent pinning any filesystem mounts
- os.chdir('/')
-
- # Tell caller what pid to send future signals to
- return pid
-
-if __name__ == "__main__":
- import time
- daemonize()
- print "Hello, world, from daemon process."
- time.sleep(20)
- print "Goodbye, world, from daemon process."
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/freqz.py b/gnuradio-core/src/python/gnuradio/gruimpl/freqz.py
deleted file mode 100644
index 60dca64a58..0000000000
--- a/gnuradio-core/src/python/gnuradio/gruimpl/freqz.py
+++ /dev/null
@@ -1,344 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2005,2007 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-# This code lifted from various parts of www.scipy.org -eb 2005-01-24
-
-# Copyright (c) 2001, 2002 Enthought, Inc.
-#
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-#
-# a. Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-# b. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-# c. Neither the name of the Enthought nor the names of its contributors
-# may be used to endorse or promote products derived from this software
-# without specific prior written permission.
-#
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
-# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-# DAMAGE.
-#
-
-__all__ = ['freqz']
-
-import numpy
-from numpy import *
-Num=numpy
-
-def atleast_1d(*arys):
- """ Force a sequence of arrays to each be at least 1D.
-
- Description:
- Force an array to be at least 1D. If an array is 0D, the
- array is converted to a single row of values. Otherwise,
- the array is unaltered.
- Arguments:
- *arys -- arrays to be converted to 1 or more dimensional array.
- Returns:
- input array converted to at least 1D array.
- """
- res = []
- for ary in arys:
- ary = asarray(ary)
- if len(ary.shape) == 0:
- result = numpy.array([ary[0]])
- else:
- result = ary
- res.append(result)
- if len(res) == 1:
- return res[0]
- else:
- return res
-
-
-def polyval(p,x):
- """Evaluate the polynomial p at x. If x is a polynomial then composition.
-
- Description:
-
- If p is of length N, this function returns the value:
- p[0]*(x**N-1) + p[1]*(x**N-2) + ... + p[N-2]*x + p[N-1]
-
- x can be a sequence and p(x) will be returned for all elements of x.
- or x can be another polynomial and the composite polynomial p(x) will be
- returned.
- """
- p = asarray(p)
- if isinstance(x,poly1d):
- y = 0
- else:
- x = asarray(x)
- y = numpy.zeros(x.shape,x.typecode())
- for i in range(len(p)):
- y = x * y + p[i]
- return y
-
-class poly1d:
- """A one-dimensional polynomial class.
-
- p = poly1d([1,2,3]) constructs the polynomial x**2 + 2 x + 3
-
- p(0.5) evaluates the polynomial at the location
- p.r is a list of roots
- p.c is the coefficient array [1,2,3]
- p.order is the polynomial order (after leading zeros in p.c are removed)
- p[k] is the coefficient on the kth power of x (backwards from
- sequencing the coefficient array.
-
- polynomials can be added, substracted, multplied and divided (returns
- quotient and remainder).
- asarray(p) will also give the coefficient array, so polynomials can
- be used in all functions that accept arrays.
- """
- def __init__(self, c_or_r, r=0):
- if isinstance(c_or_r,poly1d):
- for key in c_or_r.__dict__.keys():
- self.__dict__[key] = c_or_r.__dict__[key]
- return
- if r:
- c_or_r = poly(c_or_r)
- c_or_r = atleast_1d(c_or_r)
- if len(c_or_r.shape) > 1:
- raise ValueError, "Polynomial must be 1d only."
- c_or_r = trim_zeros(c_or_r, trim='f')
- if len(c_or_r) == 0:
- c_or_r = numpy.array([0])
- self.__dict__['coeffs'] = c_or_r
- self.__dict__['order'] = len(c_or_r) - 1
-
- def __array__(self,t=None):
- if t:
- return asarray(self.coeffs,t)
- else:
- return asarray(self.coeffs)
-
- def __coerce__(self,other):
- return None
-
- def __repr__(self):
- vals = repr(self.coeffs)
- vals = vals[6:-1]
- return "poly1d(%s)" % vals
-
- def __len__(self):
- return self.order
-
- def __str__(self):
- N = self.order
- thestr = "0"
- for k in range(len(self.coeffs)):
- coefstr ='%.4g' % abs(self.coeffs[k])
- if coefstr[-4:] == '0000':
- coefstr = coefstr[:-5]
- power = (N-k)
- if power == 0:
- if coefstr != '0':
- newstr = '%s' % (coefstr,)
- else:
- if k == 0:
- newstr = '0'
- else:
- newstr = ''
- elif power == 1:
- if coefstr == '0':
- newstr = ''
- elif coefstr == '1':
- newstr = 'x'
- else:
- newstr = '%s x' % (coefstr,)
- else:
- if coefstr == '0':
- newstr = ''
- elif coefstr == '1':
- newstr = 'x**%d' % (power,)
- else:
- newstr = '%s x**%d' % (coefstr, power)
-
- if k > 0:
- if newstr != '':
- if self.coeffs[k] < 0:
- thestr = "%s - %s" % (thestr, newstr)
- else:
- thestr = "%s + %s" % (thestr, newstr)
- elif (k == 0) and (newstr != '') and (self.coeffs[k] < 0):
- thestr = "-%s" % (newstr,)
- else:
- thestr = newstr
- return _raise_power(thestr)
-
-
- def __call__(self, val):
- return polyval(self.coeffs, val)
-
- def __mul__(self, other):
- if isscalar(other):
- return poly1d(self.coeffs * other)
- else:
- other = poly1d(other)
- return poly1d(polymul(self.coeffs, other.coeffs))
-
- def __rmul__(self, other):
- if isscalar(other):
- return poly1d(other * self.coeffs)
- else:
- other = poly1d(other)
- return poly1d(polymul(self.coeffs, other.coeffs))
-
- def __add__(self, other):
- other = poly1d(other)
- return poly1d(polyadd(self.coeffs, other.coeffs))
-
- def __radd__(self, other):
- other = poly1d(other)
- return poly1d(polyadd(self.coeffs, other.coeffs))
-
- def __pow__(self, val):
- if not isscalar(val) or int(val) != val or val < 0:
- raise ValueError, "Power to non-negative integers only."
- res = [1]
- for k in range(val):
- res = polymul(self.coeffs, res)
- return poly1d(res)
-
- def __sub__(self, other):
- other = poly1d(other)
- return poly1d(polysub(self.coeffs, other.coeffs))
-
- def __rsub__(self, other):
- other = poly1d(other)
- return poly1d(polysub(other.coeffs, self.coeffs))
-
- def __div__(self, other):
- if isscalar(other):
- return poly1d(self.coeffs/other)
- else:
- other = poly1d(other)
- return map(poly1d,polydiv(self.coeffs, other.coeffs))
-
- def __rdiv__(self, other):
- if isscalar(other):
- return poly1d(other/self.coeffs)
- else:
- other = poly1d(other)
- return map(poly1d,polydiv(other.coeffs, self.coeffs))
-
- def __setattr__(self, key, val):
- raise ValueError, "Attributes cannot be changed this way."
-
- def __getattr__(self, key):
- if key in ['r','roots']:
- return roots(self.coeffs)
- elif key in ['c','coef','coefficients']:
- return self.coeffs
- elif key in ['o']:
- return self.order
- else:
- return self.__dict__[key]
-
- def __getitem__(self, val):
- ind = self.order - val
- if val > self.order:
- return 0
- if val < 0:
- return 0
- return self.coeffs[ind]
-
- def __setitem__(self, key, val):
- ind = self.order - key
- if key < 0:
- raise ValueError, "Does not support negative powers."
- if key > self.order:
- zr = numpy.zeros(key-self.order,self.coeffs.typecode())
- self.__dict__['coeffs'] = numpy.concatenate((zr,self.coeffs))
- self.__dict__['order'] = key
- ind = 0
- self.__dict__['coeffs'][ind] = val
- return
-
- def integ(self, m=1, k=0):
- return poly1d(polyint(self.coeffs,m=m,k=k))
-
- def deriv(self, m=1):
- return poly1d(polyder(self.coeffs,m=m))
-
-def freqz(b, a, worN=None, whole=0, plot=None):
- """Compute frequency response of a digital filter.
-
- Description:
-
- Given the numerator (b) and denominator (a) of a digital filter compute
- its frequency response.
-
- jw -jw -jmw
- jw B(e) b[0] + b[1]e + .... + b[m]e
- H(e) = ---- = ------------------------------------
- jw -jw -jnw
- A(e) a[0] + a[2]e + .... + a[n]e
-
- Inputs:
-
- b, a --- the numerator and denominator of a linear filter.
- worN --- If None, then compute at 512 frequencies around the unit circle.
- If a single integer, the compute at that many frequencies.
- Otherwise, compute the response at frequencies given in worN
- whole -- Normally, frequencies are computed from 0 to pi (upper-half of
- unit-circle. If whole is non-zero compute frequencies from 0
- to 2*pi.
-
- Outputs: (h,w)
-
- h -- The frequency response.
- w -- The frequencies at which h was computed.
- """
- b, a = map(atleast_1d, (b,a))
- if whole:
- lastpoint = 2*pi
- else:
- lastpoint = pi
- if worN is None:
- N = 512
- w = Num.arange(0,lastpoint,lastpoint/N)
- elif isinstance(worN, types.IntType):
- N = worN
- w = Num.arange(0,lastpoint,lastpoint/N)
- else:
- w = worN
- w = atleast_1d(w)
- zm1 = exp(-1j*w)
- h = polyval(b[::-1], zm1) / polyval(a[::-1], zm1)
- # if not plot is None:
- # plot(w, h)
- return h, w
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/gnuplot_freqz.py b/gnuradio-core/src/python/gnuradio/gruimpl/gnuplot_freqz.py
deleted file mode 100755
index 18dcbec3eb..0000000000
--- a/gnuradio-core/src/python/gnuradio/gruimpl/gnuplot_freqz.py
+++ /dev/null
@@ -1,102 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2005,2007 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-__all__ = ['gnuplot_freqz']
-
-import tempfile
-import os
-import math
-import numpy
-
-from gnuradio import gr
-from gnuradio.gruimpl.freqz import freqz
-
-
-def gnuplot_freqz (hw, Fs=None, logfreq=False):
-
- """hw is a tuple of the form (h, w) where h is sequence of complex
- freq responses, and w is a sequence of corresponding frequency
- points. Plot the frequency response using gnuplot. If Fs is
- provide, use it as the sampling frequency, else use 2*pi.
-
- Returns a handle to the gnuplot graph. When the handle is reclaimed
- the graph is torn down."""
-
- data_file = tempfile.NamedTemporaryFile ()
- cmd_file = os.popen ('gnuplot', 'w')
-
- h, w = hw
- ampl = 20 * numpy.log10 (numpy.absolute (h) + 1e-9)
- phase = map (lambda x: math.atan2 (x.imag, x.real), h)
-
- if Fs:
- w *= (Fs/(2*math.pi))
-
- for freq, a, ph in zip (w, ampl, phase):
- data_file.write ("%g\t%g\t%g\n" % (freq, a, ph))
-
- data_file.flush ()
-
- cmd_file.write ("set grid\n")
- if logfreq:
- cmd_file.write ("set logscale x\n")
- else:
- cmd_file.write ("unset logscale x\n")
- cmd_file.write ("plot '%s' using 1:2 with lines\n" % (data_file.name,))
- cmd_file.flush ()
-
- return (cmd_file, data_file)
-
-
-def test_plot ():
- sample_rate = 2.0e6
- #taps = firdes.low_pass(1, sample_rate, 200000, 100000, firdes.WIN_HAMMING)
- taps = (0.0007329441141337156, 0.0007755281985737383, 0.0005323155201040208,
- -7.679847761841656e-19, -0.0007277769618667662, -0.001415981911122799,
- -0.0017135187517851591, -0.001282231998629868, 1.61239866282397e-18,
- 0.0018589380197227001, 0.0035909228026866913, 0.004260237794369459,
- 0.00310456077568233, -3.0331308923229716e-18, -0.004244099836796522,
- -0.007970594801008701, -0.009214458055794239, -0.006562007591128349,
- 4.714311174044374e-18, 0.008654761128127575, 0.01605774275958538,
- 0.01841980405151844, 0.013079923577606678, -6.2821650235090215e-18,
- -0.017465557903051376, -0.032989680767059326, -0.03894065320491791,
- -0.028868533670902252, 7.388111706347014e-18, 0.04517475143074989,
- 0.09890196472406387, 0.14991308748722076, 0.18646684288978577,
- 0.19974154233932495, 0.18646684288978577, 0.14991308748722076,
- 0.09890196472406387, 0.04517475143074989, 7.388111706347014e-18,
- -0.028868533670902252, -0.03894065320491791, -0.032989680767059326,
- -0.017465557903051376, -6.2821650235090215e-18, 0.013079923577606678,
- 0.01841980405151844, 0.01605774275958538, 0.008654761128127575,
- 4.714311174044374e-18, -0.006562007591128349, -0.009214458055794239,
- -0.007970594801008701, -0.004244099836796522, -3.0331308923229716e-18,
- 0.00310456077568233, 0.004260237794369459, 0.0035909228026866913,
- 0.0018589380197227001, 1.61239866282397e-18, -0.001282231998629868,
- -0.0017135187517851591, -0.001415981911122799, -0.0007277769618667662,
- -7.679847761841656e-19, 0.0005323155201040208, 0.0007755281985737383,
- 0.0007329441141337156)
-
- # print len (taps)
- return gnuplot_freqz (freqz (taps, 1), sample_rate)
-
-if __name__ == '__main__':
- handle = test_plot ()
- raw_input ('Press Enter to continue: ')
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/hexint.py b/gnuradio-core/src/python/gnuradio/gruimpl/hexint.py
deleted file mode 100644
index 0fb5ecde04..0000000000
--- a/gnuradio-core/src/python/gnuradio/gruimpl/hexint.py
+++ /dev/null
@@ -1,44 +0,0 @@
-#
-# Copyright 2005 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-def hexint(mask):
- """
- Convert unsigned masks into signed ints.
-
- This allows us to use hex constants like 0xf0f0f0f2 when talking to
- our hardware and not get screwed by them getting treated as python
- longs.
- """
- if mask >= 2**31:
- return int(mask-2**32)
- return mask
-
-def hexshort(mask):
- """
- Convert unsigned masks into signed shorts.
-
- This allows us to use hex constants like 0x8000 when talking to
- our hardware and not get screwed by them getting treated as python
- longs.
- """
- if mask >= 2**15:
- return int(mask-2**16)
- return mask
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/listmisc.py b/gnuradio-core/src/python/gnuradio/gruimpl/listmisc.py
deleted file mode 100644
index 9e70eb863c..0000000000
--- a/gnuradio-core/src/python/gnuradio/gruimpl/listmisc.py
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# Copyright 2005 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-def list_reverse(x):
- """
- Return a copy of x that is reverse order.
- """
- r = list(x)
- r.reverse()
- return r
-
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/mathmisc.py b/gnuradio-core/src/python/gnuradio/gruimpl/mathmisc.py
deleted file mode 100644
index 7e6f23a346..0000000000
--- a/gnuradio-core/src/python/gnuradio/gruimpl/mathmisc.py
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# Copyright 2005 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-import math
-
-def gcd(a,b):
- while b:
- a,b = b, a % b
- return a
-
-def lcm(a,b):
- return a * b / gcd(a, b)
-
-def log2(x):
- return math.log(x)/math.log(2)
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/msgq_runner.py b/gnuradio-core/src/python/gnuradio/gruimpl/msgq_runner.py
deleted file mode 100644
index 767a74a717..0000000000
--- a/gnuradio-core/src/python/gnuradio/gruimpl/msgq_runner.py
+++ /dev/null
@@ -1,82 +0,0 @@
-#
-# Copyright 2009 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-"""
-Convenience class for dequeuing messages from a gr.msg_queue and
-invoking a callback.
-
-Creates a Python thread that does a blocking read on the supplied
-gr.msg_queue, then invokes callback each time a msg is received.
-
-If the msg type is not 0, then it is treated as a signal to exit
-its loop.
-
-If the callback raises an exception, and the runner was created
-with 'exit_on_error' equal to True, then the runner will store the
-exception and exit its loop, otherwise the exception is ignored.
-
-To get the exception that the callback raised, if any, call
-exit_error() on the object.
-
-To manually stop the runner, call stop() on the object.
-
-To determine if the runner has exited, call exited() on the object.
-"""
-
-from gnuradio import gr
-import gnuradio.gr.gr_threading as _threading
-
-class msgq_runner(_threading.Thread):
-
- def __init__(self, msgq, callback, exit_on_error=False):
- _threading.Thread.__init__(self)
-
- self._msgq = msgq
- self._callback = callback
- self._exit_on_error = exit_on_error
- self._done = False
- self._exited = False
- self._exit_error = None
- self.setDaemon(1)
- self.start()
-
- def run(self):
- while not self._done:
- msg = self._msgq.delete_head()
- if msg.type() != 0:
- self.stop()
- else:
- try:
- self._callback(msg)
- except Exception, e:
- if self._exit_on_error:
- self._exit_error = e
- self.stop()
- self._exited = True
-
- def stop(self):
- self._done = True
-
- def exited(self):
- return self._exited
-
- def exit_error(self):
- return self._exit_error
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/os_read_exactly.py b/gnuradio-core/src/python/gnuradio/gruimpl/os_read_exactly.py
deleted file mode 100644
index 40b053770e..0000000000
--- a/gnuradio-core/src/python/gnuradio/gruimpl/os_read_exactly.py
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Copyright 2005 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-import os
-
-def os_read_exactly(file_descriptor, nbytes):
- """
- Replacement for os.read that blocks until it reads exactly nbytes.
-
- """
- s = ''
- while nbytes > 0:
- sbuf = os.read(file_descriptor, nbytes)
- if not(sbuf):
- return ''
- nbytes -= len(sbuf)
- s = s + sbuf
- return s
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/seq_with_cursor.py b/gnuradio-core/src/python/gnuradio/gruimpl/seq_with_cursor.py
deleted file mode 100644
index def3299b69..0000000000
--- a/gnuradio-core/src/python/gnuradio/gruimpl/seq_with_cursor.py
+++ /dev/null
@@ -1,77 +0,0 @@
-#
-# Copyright 2003,2004 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-# misc utilities
-
-import types
-import exceptions
-
-class seq_with_cursor (object):
- __slots__ = [ 'items', 'index' ]
-
- def __init__ (self, items, initial_index = None, initial_value = None):
- assert len (items) > 0, "seq_with_cursor: len (items) == 0"
- self.items = items
- self.set_index (initial_index)
- if initial_value is not None:
- self.set_index_by_value(initial_value)
-
- def set_index (self, initial_index):
- if initial_index is None:
- self.index = len (self.items) / 2
- elif initial_index >= 0 and initial_index < len (self.items):
- self.index = initial_index
- else:
- raise exceptions.ValueError
-
- def set_index_by_value(self, v):
- """
- Set index to the smallest value such that items[index] >= v.
- If there is no such item, set index to the maximum value.
- """
- self.set_index(0) # side effect!
- cv = self.current()
- more = True
- while cv < v and more:
- cv, more = self.next() # side effect!
-
- def next (self):
- new_index = self.index + 1
- if new_index < len (self.items):
- self.index = new_index
- return self.items[new_index], True
- else:
- return self.items[self.index], False
-
- def prev (self):
- new_index = self.index - 1
- if new_index >= 0:
- self.index = new_index
- return self.items[new_index], True
- else:
- return self.items[self.index], False
-
- def current (self):
- return self.items[self.index]
-
- def get_seq (self):
- return self.items[:] # copy of items
-
diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/socket_stuff.py b/gnuradio-core/src/python/gnuradio/gruimpl/socket_stuff.py
deleted file mode 100644
index 489b6ab255..0000000000
--- a/gnuradio-core/src/python/gnuradio/gruimpl/socket_stuff.py
+++ /dev/null
@@ -1,62 +0,0 @@
-#
-# Copyright 2005 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 3, 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., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-# random socket related stuff
-
-import socket
-import os
-import sys
-
-def tcp_connect_or_die(sock_addr):
- """
-
- Args:
- sock_addr: (host, port) to connect to (tuple)
-
- Returns:
- : socket or exits
- """
- s = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
- try:
- s.connect(sock_addr)
- except socket.error, err:
- sys.stderr.write('Failed to connect to %s: %s\n' %
- (sock_addr, os.strerror (err.args[0]),))
- sys.exit(1)
- return s
-
-def udp_connect_or_die(sock_addr):
- """
-
- Args:
- sock_addr: (host, port) to connect to (tuple)
-
- Returns:
- : socket or exits
- """
- s = socket.socket (socket.AF_INET, socket.SOCK_DGRAM)
- try:
- s.connect(sock_addr)
- except socket.error, err:
- sys.stderr.write('Failed to connect to %s: %s\n' %
- (sock_addr, os.strerror (err.args[0]),))
- sys.exit(1)
- return s