[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] r5634 - in grc/branches/jblum_work/src: . Graphics
From: |
jblum |
Subject: |
[Commit-gnuradio] r5634 - in grc/branches/jblum_work/src: . Graphics |
Date: |
Sun, 3 Jun 2007 08:14:57 -0600 (MDT) |
Author: jblum
Date: 2007-06-03 08:14:56 -0600 (Sun, 03 Jun 2007)
New Revision: 5634
Modified:
grc/branches/jblum_work/src/ActionHandler.py
grc/branches/jblum_work/src/Actions.py
grc/branches/jblum_work/src/DataType.py
grc/branches/jblum_work/src/Graphics/Bars.py
grc/branches/jblum_work/src/Graphics/Dialogs.py
grc/branches/jblum_work/src/Graphics/__init__.py
grc/branches/jblum_work/src/MathExprParser.py
Log:
created help display for math expressions, added a data type for raw
expressions, added intelligent casting to functions
Modified: grc/branches/jblum_work/src/ActionHandler.py
===================================================================
--- grc/branches/jblum_work/src/ActionHandler.py 2007-06-03 05:23:38 UTC
(rev 5633)
+++ grc/branches/jblum_work/src/ActionHandler.py 2007-06-03 14:14:56 UTC
(rev 5634)
@@ -140,7 +140,7 @@
# enable a select few actions
Graphics.enable_usrp_diagnostics() #try to enable
usrp diagnostics
for action in (APPLICATION_QUIT, FLOW_GRAPH_NEW,
FLOW_GRAPH_OPEN, FLOW_GRAPH_SAVE_AS,
-
ABOUT_WINDOW_DISPLAY, COLORS_WINDOW_DISPLAY, HOTKEYS_WINDOW_DISPLAY,
+
ABOUT_WINDOW_DISPLAY, COLORS_WINDOW_DISPLAY, HOTKEYS_WINDOW_DISPLAY,
MATH_EXPR_WINDOW_DISPLAY,
FLOW_GRAPH_WINDOW_RESIZE, PREFS_WINDOW_DISPLAY, FLOW_GRAPH_SNAP_SHOT):
get_action_from_name(action).set_sensitive(True)
if self.flow_graph_file_path == '':
@@ -233,6 +233,8 @@
Graphics.DataTypeColorsDialog()
elif state == HOTKEYS_WINDOW_DISPLAY:
Graphics.HotKeysDialog()
+ elif state == MATH_EXPR_WINDOW_DISPLAY:
+ Graphics.MathExprDialog()
elif state == FLOW_GRAPH_WINDOW_RESIZE:
dimensions =
Graphics.FlowGraphWindowSizeDialog(self.flow_graph).run()
if dimensions != None:
Modified: grc/branches/jblum_work/src/Actions.py
===================================================================
--- grc/branches/jblum_work/src/Actions.py 2007-06-03 05:23:38 UTC (rev
5633)
+++ grc/branches/jblum_work/src/Actions.py 2007-06-03 14:14:56 UTC (rev
5634)
@@ -73,6 +73,7 @@
HOTKEYS_WINDOW_DISPLAY = 'hotkeys window display'
USRP_DIAGNOSTICS_DISPLAY = 'usrp diagnostics display'
PREFS_WINDOW_DISPLAY = 'prefs window display'
+MATH_EXPR_WINDOW_DISPLAY = 'expression window display'
######################################################################################################
# actions
@@ -96,6 +97,7 @@
gtk.Action(ABOUT_WINDOW_DISPLAY, '_About', 'About this program',
'gtk-about'),
gtk.Action(COLORS_WINDOW_DISPLAY, '_Colors', 'Data Type Colors',
'gtk-select-color'),
gtk.Action(HOTKEYS_WINDOW_DISPLAY, '_HotKeys', 'Hot Keys', 'gtk-info'),
+ gtk.Action(MATH_EXPR_WINDOW_DISPLAY, '_Math Expressions', 'Mathematical
Expressions', 'gtk-convert'),
gtk.Action(FLOW_GRAPH_RUN, '_Run', 'Run the flow graph', 'gtk-execute'),
gtk.Action(FLOW_GRAPH_STOP, '_Stop', 'Stop the flow graph', 'gtk-stop'),
gtk.Action(FLOW_GRAPH_SNAP_SHOT, 'S_nap Shot', 'Take a snap shot image
of the flow graph', 'gtk-print'),
Modified: grc/branches/jblum_work/src/DataType.py
===================================================================
--- grc/branches/jblum_work/src/DataType.py 2007-06-03 05:23:38 UTC (rev
5633)
+++ grc/branches/jblum_work/src/DataType.py 2007-06-03 14:14:56 UTC (rev
5634)
@@ -124,6 +124,17 @@
#############################################################################################
# Special Types
#############################################################################################
+class RawExpr(DataType):
+ ''' A raw mathematical expression. '''
+ type = 'raw'
+ def __init__(self, data=''):
+ ''' Raw data type contructor. Default value is blank string.
'''
+ DataType.__init__(self, data)
+ def parse(self):
+ ''' Return the raw data returned by the parser '''
+ data = DataType.parse(self)
+ return MathExprParser.eval_expr(data)
+
class String(DataType):
''' The string data type. '''
type = 'string'
@@ -314,11 +325,5 @@
if __name__ == '__main__':
print "put things here to test DataTypes"
- dt = String('2fsg56', min=3, max=5)
- print dt.is_valid()
- dt = IntVector('2, 3,', min=3, max=5)
- print dt.is_valid()
- dt = Hex('0xfe', min=0, max=254)
- print dt.is_valid()
\ No newline at end of file
Modified: grc/branches/jblum_work/src/Graphics/Bars.py
===================================================================
--- grc/branches/jblum_work/src/Graphics/Bars.py 2007-06-03 05:23:38 UTC
(rev 5633)
+++ grc/branches/jblum_work/src/Graphics/Bars.py 2007-06-03 14:14:56 UTC
(rev 5634)
@@ -76,7 +76,6 @@
(gtk.Action('Options',
'_Options', None, None),
[
FLOW_GRAPH_WINDOW_RESIZE,
-
USRP_DIAGNOSTICS_DISPLAY,
PREFS_WINDOW_DISPLAY,
]),
(gtk.Action('Help', '_Help',
None, None),
@@ -84,6 +83,8 @@
ABOUT_WINDOW_DISPLAY,
COLORS_WINDOW_DISPLAY,
HOTKEYS_WINDOW_DISPLAY,
+
MATH_EXPR_WINDOW_DISPLAY,
+
USRP_DIAGNOSTICS_DISPLAY,
])
]
Modified: grc/branches/jblum_work/src/Graphics/Dialogs.py
===================================================================
--- grc/branches/jblum_work/src/Graphics/Dialogs.py 2007-06-03 05:23:38 UTC
(rev 5633)
+++ grc/branches/jblum_work/src/Graphics/Dialogs.py 2007-06-03 14:14:56 UTC
(rev 5634)
@@ -198,3 +198,82 @@
self.vbox.pack_start(label)
self.run()
self.destroy()
+
+######################################################################################################
+class MathExprDialog(gtk.Dialog):
+ """ A dialog to test math expressions for the parser. """
+ HELP_MSG = """\
+<span size="small">
+<b>Operators - Complex <i>(complex arguments)</i></b>
+ + - * / ^
+
+<b>Trigonometric Functions <i>(complex arguments, radians)</i></b>
+ sin(z) cos(z) tan(z) asin(z) acos(z) atan(z)
+ sinh(z) cosh(z) tanh(z) asinh(z) acosh(z) atanh(z)
+
+<b>Misc Functions <i>(complex arguments)</i></b>
+ pow(b, p) sqrt(z)
+ abs(z*) mag(z*) real(z*) imag(z*) conj(z*) - z can be a vector
+ arg(z) - complex angle
+ log10(z) log(z, [b=e]) ln(z) exp(z)
+
+<b>Misc Functions <i>(floating point arguments)</i></b>
+ floor(f) ceil(f) radians(deg) degrees(rad) mod(f1, f2) atan2(y, x)
sgn(f)
+
+<b>Filter Taps Generators <i>(floating point arguments)</i></b>
+ low_pass(gain, samp_rate, cutoff_freq, width, [window=hamming],
[beta=6.76])
+ high_pass(gain, samp_rate, cutoff_freq, width, [window=hamming],
[beta=6.76])
+ band_pass(gain, samp_rate, low_cutoff_freq, high_cutoff_freq, width,
[window=hamming], [beta=6.76])
+ complex_band_pass(gain, samp_rate, low_cutoff_freq, high_cutoff_freq,
width, [window=hamming], [beta=6.76])
+ band_reject(gain, samp_rate, low_cutoff_freq, high_cutoff_freq, width,
[window=hamming], [beta=6.76])
+ gaussian(gain, spb, bt, int ntaps)
+ hilbert(int ntaps, [window=rectangular], [beta=6.76])
+ root_raised_cosine(gain, samp_rate, symbol_rate, alpha, int ntaps)
+ window(window, int ntaps, beta)
+
+<b>Window Types for Filters</b>
+ hamming hann blackman rectangular kaiser
+
+<b>Using Vectors</b>
+ () (num1,) (num2, num2, ...)
+
+<b>Test Your Expressions Below:</b>
+</span>\
+"""
+ def __init__(self):
+ """ Create a new gtk Dialog with a close button, an extry
box, and an output text box. """
+ gtk.Dialog.__init__(self, buttons=('gtk-close',
gtk.RESPONSE_CLOSE))
+ # Create the title and label #
+ self.set_title('Mathematical Expressions')
+ label = gtk.Label()
+ label.set_markup(self.HELP_MSG)
+ label.show()
+ self.vbox.pack_start(label, False)
+ self.set_size_request(600, 600)
+ # create the entry box and connect it to a new handler #
+ self.param = GraphicalParam('Expression', RawExpr(''))
+ self.input_obj = self.param.get_input_object()
+ self.input_obj.entry.connect("changed", self.handle_changed)
+ self.vbox.pack_start(self.input_obj, False)
+ # create a text box for parser output #
+ self.text_box = TextDisplay()
+ self.text_box.set_text('')
+ # add the scrolled window for the text box #
+ scrolled_window = gtk.ScrolledWindow()
+ scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,
gtk.POLICY_AUTOMATIC)
+ scrolled_window.add_with_viewport(self.text_box)
+ scrolled_window.show()
+ self.vbox.pack_start(scrolled_window, True)
+ self.handle_changed() #initial display
+ self.run()
+ self.destroy()
+
+ def handle_changed(self, widget=None):
+ ''' Handle changed in the param's entry box.
+ Call the default change handler and then update the
text box. '''
+ self.param.handle_changed()
+ if self.param.get_data_type().is_valid():
+ text = str(self.param.get_data_type().parse())
+ else: text = self.param.get_data_type().msg
+ self.text_box.set_text(text)
+
\ No newline at end of file
Modified: grc/branches/jblum_work/src/Graphics/__init__.py
===================================================================
--- grc/branches/jblum_work/src/Graphics/__init__.py 2007-06-03 05:23:38 UTC
(rev 5633)
+++ grc/branches/jblum_work/src/Graphics/__init__.py 2007-06-03 14:14:56 UTC
(rev 5634)
@@ -24,5 +24,5 @@
# only import the modules that need external access #
from MainWindow import MainWindow
from FlowGraphFileDialog import FlowGraphFileDialog
-from Dialogs import
PreferencesDialog,FlowGraphWindowSizeDialog,LooseChangesMessage,AboutDialog,DataTypeColorsDialog,HotKeysDialog
+from Dialogs import
PreferencesDialog,FlowGraphWindowSizeDialog,LooseChangesMessage,AboutDialog,DataTypeColorsDialog,HotKeysDialog,MathExprDialog
from USRPDiagnostics import USRPDiagnosticsDialog,enable_usrp_diagnostics
Modified: grc/branches/jblum_work/src/MathExprParser.py
===================================================================
--- grc/branches/jblum_work/src/MathExprParser.py 2007-06-03 05:23:38 UTC
(rev 5633)
+++ grc/branches/jblum_work/src/MathExprParser.py 2007-06-03 14:14:56 UTC
(rev 5634)
@@ -21,7 +21,8 @@
Josh Blum
This file provides:
eval_expr for evaluating string expressions,
- verify_complex, verify_float, verify_int for casting numbers.
+ verify_complex, verify_float, verify_int for casting numbers,
+ and verify_number for picking the best representation.
"""
import math,cmath
@@ -32,9 +33,9 @@
_WHITESPACE = (' ', '\t', '')
_CONSTANTS = { #constans must be lower case
- 'pi' : complex(cmath.pi),
- 'e' : complex(cmath.e),
- 'j' : complex(1j),
+ 'pi' : cmath.pi,
+ 'e' : cmath.e,
+ 'j' : 1j,
'hamming' : gr.firdes.WIN_HAMMING, #filter windows
'hann' : gr.firdes.WIN_HANN,
@@ -44,11 +45,11 @@
}
#########################################################
-## Complex mathematical functions
+## Number parsers
#########################################################
def verify_complex(num):
- ''' Verify that the number is indeed a number.
+ ''' Verify that the number is a complex number.
Raise an exception if number cannot be cast to a complex.
Return the value as a complex. '''
try: c_num = complex(num) #ensure that the num can be complex
@@ -72,20 +73,36 @@
if f_num - int(f_num) != 0: raise ValueError('Expected an integer but
found "%s".'%(f_num,))
return int(f_num)
+def verify_number(num):
+ ''' Try to cast the number into its most primative form.
+ In this order: int, float, or complex.
+ Raise an exception if num is not a number.
+ Return a number of type listed above. '''
+ try: return verify_int(num) #try int
+ except:
+ try: return verify_float(num) #try float
+ except: return verify_complex(num) #complex or fail
+
+#########################################################
+## Complex mathematical functions
+#########################################################
+
def _complex_abs_v(*args):
''' Compute the abs of a complex number or vector. '''
sum = 0
for arg in args:
if _is_list(arg): sum = sum + _complex_abs_v(*arg)
- else: sum = sum + complex(arg).real*complex(arg).real +
complex(arg).imag*complex(arg).imag
- return complex(sum**0.5)
+ else: sum = sum + \
+ verify_complex(arg).real*verify_complex(arg).real + \
+ verify_complex(arg).imag*verify_complex(arg).imag
+ return verify_number(cmath.sqrt(sum))
def _complex_real_v(*args):
''' Get the real part of a number or vector. '''
result = list()
for arg in args:
if _is_list(arg): result.append(_complex_real_v(*arg))
- else: result.append(complex(complex(arg).real))
+ else: result.append(verify_number(verify_complex(arg).real))
return result
def _complex_imag_v(*args):
@@ -93,7 +110,7 @@
result = list()
for arg in args:
if _is_list(arg): result.append(_complex_imag_v(*arg))
- else: result.append(complex(complex(arg).imag))
+ else: result.append(verify_number(verify_complex(arg).imag))
return result
def _complex_conj_v(*args):
@@ -101,12 +118,12 @@
result = list()
for arg in args:
if _is_list(arg): result.append(_complex_conj_v(*arg))
- else: result.append(complex(complex(arg).conjugate()))
+ else:
result.append(verify_number(verify_complex(arg).conjugate()))
return result
def _complex_arg(arg):
''' Get the angle of the complex number (radians). '''
- return complex(math.atan2(complex(arg).imag, complex(arg).real))
+ return verify_number(math.atan2(verify_complex(arg).imag,
verify_complex(arg).real))
def _handle_filter(filter, *filter_args):
''' Pass the filter arguments to the filter function.
@@ -120,8 +137,8 @@
gr.firdes.band_reject : ((5, 6, 7), (0, 1, 2, 3, 4, 6), ()),
gr.firdes.complex_band_pass : ((5, 6, 7), (0, 1, 2, 3, 4, 6),
()),
- gr.firdes.high_pass : ((4, 5, 6), (0, 1, 2, 3, 4, 6), ()),
- gr.firdes.low_pass : ((4, 5, 6), (0, 1, 2, 3, 4, 6), ()),
+ gr.firdes.high_pass : ((4, 5, 6), (0, 1, 2, 3, 5), ()),
+ gr.firdes.low_pass : ((4, 5, 6), (0, 1, 2, 3, 5), ()),
gr.firdes.gaussian : ((4,), (0, 1, 2), (3,)),
gr.firdes.hilbert : ((1, 2, 3), (2,), (0,)),
@@ -134,13 +151,11 @@
for i,arg in enumerate(filter_args):
if i in floats: filter_args[i] = verify_float(arg)
if i in ints: filter_args[i] = verify_int(arg)
- taps = list(filter(*filter_args))
- # convert all taps to complex #
- for i,tap in enumerate(taps): taps[i] = complex(tap)
+ taps = list(filter(*filter_args)) #the taps must be a list
return taps
_FUNCTIONS = {
- 'pow' : lambda b, p: b**p,
+ 'pow' : lambda b, p: verify_number(b**p), #complex power
'sqrt' : cmath.sqrt,
'abs' : _complex_abs_v,
@@ -150,26 +165,26 @@
'conj' : _complex_conj_v,
'arg' : _complex_arg,
- 'sin' : cmath.sin,
- 'cos' : cmath.cos,
- 'tan' : cmath.tan,
+ 'sin' : lambda z: verify_number(cmath.sin(z)),
+ 'cos' : lambda z: verify_number(cmath.cos(z)),
+ 'tan' : lambda z: verify_number(cmath.tan(z)),
- 'asin' : cmath.asin,
- 'acos' : cmath.acos,
- 'atan' : cmath.atan,
+ 'asin' : lambda z: verify_number(cmath.asin(z)),
+ 'acos' : lambda z: verify_number(cmath.acos(z)),
+ 'atan' : lambda z: verify_number(cmath.atan(z)),
- 'sinh' : cmath.sinh, #hyperbolics
- 'cosh' : cmath.cosh,
- 'tanh' : cmath.tanh,
+ 'sinh' : lambda z: verify_number(cmath.sinh(z)), #hyperbolics
+ 'cosh' : lambda z: verify_number(cmath.cosh(z)),
+ 'tanh' : lambda z: verify_number(cmath.tanh(z)),
- 'asinh' : cmath.asinh,
- 'acosh' : cmath.acosh,
- 'atanh' : cmath.atanh,
+ 'asinh' : lambda z: verify_number(cmath.asinh(z)),
+ 'acosh' : lambda z: verify_number(cmath.acosh(z)),
+ 'atanh' : lambda z: verify_number(cmath.atanh(z)),
- 'log10' : cmath.log10,
- 'log' : cmath.log, #optional 2nd argument as base
+ 'log10' : lambda z: verify_number(cmath.log10(z)),
+ 'log' : lambda *z: verify_number(cmath.log(*z)), #optional 2nd
argument as base
'ln' : lambda z: cmath.log(z), #only allow natural log
- 'exp' : cmath.exp,
+ 'exp' : lambda z: verify_number(cmath.exp(z)),
'band_pass' : lambda *args: _handle_filter(gr.firdes.band_pass, *args),
#taps generators
'band_reject' : lambda *args: _handle_filter(gr.firdes.band_reject,
*args),
@@ -181,11 +196,13 @@
'root_raised_cosine' : lambda *args:
_handle_filter(gr.firdes.root_raised_cosine, *args),
'window' : lambda *args: _handle_filter(gr.firdes.window, *args),
- 'floor' : lambda f: complex(math.floor(verify_float(f))),
- 'ceil' : lambda f: complex(math.ceil(verify_float(f))),
- 'radians' : lambda f: complex(math.radians(verify_float(f))),
- 'degrees' : lambda f: complex(math.degrees(verify_float(f))),
- 'fmod' : lambda f1, f2: complex(math.fmod(verify_float(f1),
verify_float(f2))),
+ 'floor' : lambda f: math.floor(verify_float(f)),
+ 'ceil' : lambda f: math.ceil(verify_float(f)),
+ 'radians' : lambda f: math.radians(verify_float(f)),
+ 'degrees' : lambda f: math.degrees(verify_float(f)),
+ 'mod' : lambda f1, f2: math.fmod(verify_float(f1), verify_float(f2)),
+ 'atan2' : lambda y, x: math.atan2(verify_float(y), verify_float(x)),
+ 'sgn' : lambda f: abs(f)/f
}
#########################################################
@@ -199,7 +216,7 @@
def _is_constant(symbol): return symbol in _CONSTANTS.keys()
def _is_number(symbol):
- try: complex(symbol)
+ try: verify_number(symbol)
except: return False
return True
@@ -262,18 +279,18 @@
if not arg1_is_list and not arg2_is_list and \
_is_number(arg1) and _is_number(arg2): #non vector operations
if op == '^-':
- return arg1**(-1*arg2)
+ return verify_number(arg1**(-1*arg2))
elif op == '^':
- return arg1**arg2
+ return verify_number(arg1**arg2)
elif op == '*':
- return arg1 * arg2
+ return verify_number(arg1 * arg2)
elif op == '/':
- try: return arg1 / arg2
+ try: return verify_number(arg1 / arg2)
except ZeroDivisionError: raise
ZeroDivisionError('Cannot divide "%s" by 0.'%(arg1,))
elif op == '+':
- return arg1 + arg2
+ return verify_number(arg1 + arg2)
elif op == '-':
- return arg1 - arg2
+ return verify_number(arg1 - arg2)
raise ArithmeticError('Operation of "%s" cannot be performed on "%s",
"%s".'%(op, arg1, arg2))
#########################################################
@@ -348,12 +365,12 @@
Make comma separated values into lists (represent vectors).
Return the final value of the expression. '''
for i,element in enumerate(nested_elements):
- # simplify the nested lists #
+ # simplify the nested lists #
if _is_list(element): nested_elements[i] =
_simplify_nested_elements(element)
# substitute in values for constants #
elif _is_constant(element): nested_elements[i] =
_CONSTANTS[element]
# substitute in values for numbers #
- elif _is_number(element): nested_elements[i] = complex(element)
+ elif _is_number(element): nested_elements[i] =
verify_number(element)
# handle functions #
for function in _FUNCTIONS.keys():
while function in nested_elements:
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Commit-gnuradio] r5634 - in grc/branches/jblum_work/src: . Graphics,
jblum <=