c6b9509b293a5cbf66a2a310569a3511ee310526
[debian/gnuradio] / gr-wxgui / src / python / common.py
1 #
2 # Copyright 2008 Free Software Foundation, Inc.
3 #
4 # This file is part of GNU Radio
5 #
6 # GNU Radio is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3, or (at your option)
9 # any later version.
10 #
11 # GNU Radio is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with GNU Radio; see the file COPYING.  If not, write to
18 # the Free Software Foundation, Inc., 51 Franklin Street,
19 # Boston, MA 02110-1301, USA.
20 #
21
22 #A macro to apply an index to a key
23 index_key = lambda key, i: "%s_%d"%(key, i+1)
24
25 def _register_access_method(destination, controller, key):
26         """
27         Helper function for register access methods.
28         This helper creates distinct set and get methods for each key
29         and adds them to the destination object.
30         """
31         def set(value): controller[key] = value
32         setattr(destination, 'set_'+key, set)
33         def get(): return controller[key]
34         setattr(destination, 'get_'+key, get) 
35
36 def register_access_methods(destination, controller):
37         """
38         Register setter and getter functions in the destination object for all keys in the controller.
39         @param destination the object to get new setter and getter methods
40         @param controller the pubsub controller
41         """
42         for key in controller.keys(): _register_access_method(destination, controller, key)
43
44 ##################################################
45 # Input Watcher Thread
46 ##################################################
47 import threading
48
49 class input_watcher(threading.Thread):
50         """
51         Input watcher thread runs forever.
52         Read messages from the message queue.
53         Forward messages to the message handler.
54         """
55         def __init__ (self, msgq, controller, msg_key, arg1_key='', arg2_key=''):
56                 threading.Thread.__init__(self)
57                 self.setDaemon(1)
58                 self.msgq = msgq
59                 self._controller = controller
60                 self._msg_key = msg_key
61                 self._arg1_key = arg1_key
62                 self._arg2_key = arg2_key
63                 self.keep_running = True
64                 self.start()
65
66         def run(self):
67                 while self.keep_running:
68                         msg = self.msgq.delete_head()
69                         if self._arg1_key: self._controller[self._arg1_key] = msg.arg1()
70                         if self._arg2_key: self._controller[self._arg2_key] = msg.arg2()
71                         self._controller[self._msg_key] = msg.to_string()
72
73 ##################################################
74 # Shared Functions
75 ##################################################
76 import numpy
77 import math
78
79 def get_exp(num):
80         """
81         Get the exponent of the number in base 10.
82         @param num the floating point number
83         @return the exponent as an integer
84         """
85         if num == 0: return 0
86         return int(math.floor(math.log10(abs(num))))
87
88 def get_clean_num(num):
89         """
90         Get the closest clean number match to num with bases 1, 2, 5.
91         @param num the number
92         @return the closest number
93         """
94         if num == 0: return 0
95         sign = num > 0 and 1 or -1
96         exp = get_exp(num)
97         nums = numpy.array((1, 2, 5, 10))*(10**exp)
98         return sign*nums[numpy.argmin(numpy.abs(nums - abs(num)))]
99
100 def get_clean_incr(num):
101         """
102         Get the next higher clean number with bases 1, 2, 5.
103         @param num the number
104         @return the next higher number
105         """
106         num = get_clean_num(num)
107         exp = get_exp(num)
108         coeff = int(round(num/10**exp))
109         return {
110                 -5: -2,
111                 -2: -1,
112                 -1: -.5,
113                 1: 2,
114                 2: 5,
115                 5: 10,
116         }[coeff]*(10**exp)
117
118 def get_clean_decr(num):
119         """
120         Get the next lower clean number with bases 1, 2, 5.
121         @param num the number
122         @return the next lower number
123         """
124         num = get_clean_num(num)
125         exp = get_exp(num)
126         coeff = int(round(num/10**exp))
127         return {
128                 -5: -10,
129                 -2: -5,
130                 -1: -2,
131                 1: .5,
132                 2: 1,
133                 5: 2,
134         }[coeff]*(10**exp)
135
136 def get_min_max(samples):
137         """
138         Get the minimum and maximum bounds for an array of samples.
139         @param samples the array of real values
140         @return a tuple of min, max
141         """
142         scale_factor = 3
143         mean = numpy.average(samples)
144         rms = numpy.max([scale_factor*((numpy.sum((samples-mean)**2)/len(samples))**.5), .1])
145         min = mean - rms
146         max = mean + rms
147         return min, max