source: fact/tools/pyscripts/pyfact/generator.py@ 13430

Last change on this file since 13430 was 13420, checked in by neise, 13 years ago
new class Signal Generator CSV
  • Property svn:executable set to *
File size: 8.7 KB
Line 
1#!/usr/bin/python -tt
2#
3# Dominik Neise, Werner Lustermann
4# TU Dortmund, ETH Zurich
5#
6import numpy as np
7
8class SignalGenerator(object):
9 """ Signal Generator
10 generates signals for testing several helper classes like:
11 * fir filters
12 * signal extractors
13 """
14
15 def __init__(self, option_str = 'len 100 noise 3', name = 'SignalGenerator'):
16 """ initialize the generator
17 sets default signal to generate
18 """
19 self.__module__ = 'generator'
20 self.option_str = option_str.lower()
21 self.options = make_options_from_str(option_str)
22 self.parse_options()
23 self.name = name
24
25 def parse_options(self):
26 o = self.options #shortcut
27 if 'len' in o:
28 self.npoints = int(o['len'][0])
29 else:
30 self.npoints = 100
31 if 'noise' in o:
32 self.sigma = float(o['noise'][0])
33 else:
34 self.sigma = 1
35 if 'bsl' in o:
36 self.bsl = float(o['bsl'][0])
37 else:
38 self.bsl = -0.5
39
40 if 'step' in o:
41 self.step_height = float(o['step'][0])
42 self.step_start = int(o['step'][1])
43 self.step_stop = int(o['step'][2])
44
45 if 'triangle' in o:
46 self.pulses = []
47 # append 1st pulse to list of pulses
48 self.pulses.append( ( float(o['triangle'][0]) , float(o['triangle'][1]), int(o['triangle'][2]), int(o['triangle'][3]) ) )
49 number_of_pulses_after_1st = (len(o['triangle'])-4)/2
50 for i in range(number_of_pulses_after_1st):
51 self.pulses.append( ( float(o['triangle'][2*i+4]) , float(o['triangle'][2*i+5]), int(o['triangle'][2]), int(o['triangle'][3]) ) )
52
53 if 'spike' in o:
54 self.spikes = []
55 for i in range(len(o['spike'])/2):
56 self.spikes.append( ( int(o['spike'][2*i]), float(o['spike'][2*i+1]) ) )
57
58 def __call__(self, option_str = ''):
59 if option_str:
60 self.option_str = option_str.lower()
61 self.options = make_options_from_str(self.option_str)
62 self.parse_options()
63
64 signal = np.zeros(self.npoints)
65 signal += self.bsl
66 signal += np.random.randn(self.npoints) * self.sigma
67 if 'step' in self.options:
68 signal[self.step_start:self.step_stop] += self.step_height
69 if 'triangle' in self.options:
70 for pulse in self.pulses:
71 pos = pulse[0]
72 height = pulse[1]
73 rise = pulse[2]
74 fall = pulse[3]
75 start = pos - rise
76 stop = pos + fall
77 signal[start:pos] += np.linspace(0., height, rise)
78 signal[pos:stop] += np.linspace(height, 0. , fall)
79 if 'spike' in self.options:
80 for spike in self.spikes:
81 signal[spike[0]] += spike[1]
82 return signal
83
84 def __str__(self):
85 s = self.name + '\n'
86 s += 'possible options and parameters\n'
87 s += ' * len: number of samples (100)\n'
88 s += ' * noise: sigma (1)\n'
89 s += ' * bsl: level (-0.5)\n'
90 s += ' * step: height, start, end\n'
91 s += ' * triangle: pos height risingedge, fallingedge [pos height ...]\n'
92 s += ' * spike: pos height [pos height ...]\n'
93
94 s += 'current options are:\n'
95 for key in self.options.keys():
96 s += key + ':' + str(self.options[key]) + '\n'
97 return s
98
99
100class SignalGeneratorCSV(object):
101
102 def __init__(self, file_name, option_str = 'len 100 noise 3', name = 'SignalGenerator'):
103 time, maxprob, mean, median = np.loadtxt( file_name, delimiter=',', unpack=True)
104 csv_data = maxprob
105
106 # csv data was downshifted, I shift it up here
107 self.csv_data = csv_data - csv_data.min()
108
109
110 self.__module__ = 'CSV generator'
111 self.option_str = option_str.lower()
112 self.options = make_options_from_str(option_str)
113 self.parse_options()
114 self.name = name
115
116 def parse_options(self):
117 o = self.options #shortcut
118 if 'len' in o:
119 self.npoints = int(o['len'][0])
120 else:
121 self.npoints = 100
122 if 'noise' in o:
123 self.sigma = float(o['noise'][0])
124 else:
125 self.sigma = 1
126 if 'bsl' in o:
127 self.bsl = float(o['bsl'][0])
128 else:
129 self.bsl = -0.5
130
131 if 'step' in o:
132 self.step_height = float(o['step'][0])
133 self.step_start = int(o['step'][1])
134 self.step_stop = int(o['step'][2])
135
136 if 'triangle' in o:
137 self.pulses = []
138 # append 1st pulse to list of pulses
139 self.pulses.append( ( float(o['triangle'][0]) , float(o['triangle'][1]), int(o['triangle'][2]), int(o['triangle'][3]) ) )
140 number_of_pulses_after_1st = (len(o['triangle'])-4)/2
141 for i in range(number_of_pulses_after_1st):
142 self.pulses.append( ( float(o['triangle'][2*i+4]) , float(o['triangle'][2*i+5]), int(o['triangle'][2]), int(o['triangle'][3]) ) )
143
144 if 'spike' in o:
145 self.spikes = []
146 for i in range(len(o['spike'])/2):
147 self.spikes.append( ( int(o['spike'][2*i]), float(o['spike'][2*i+1]) ) )
148
149 if 'csv' in o:
150 self.csvs = []
151 for i in range(len(o['csv'])/2):
152 time = int( o['csv'][2*i] )
153 amplitude = float( o['csv'][2*i+1] )
154 self.csvs.append( (time, amplitude) )
155
156 def __call__(self, option_str = ''):
157 if option_str:
158 self.option_str = option_str.lower()
159 self.options = make_options_from_str(self.option_str)
160 self.parse_options()
161
162 signal = np.zeros(self.npoints)
163 signal += self.bsl
164
165 if 'step' in self.options:
166 signal[self.step_start:self.step_stop] += self.step_height
167 if 'triangle' in self.options:
168 for pulse in self.pulses:
169 pos = pulse[0]
170 height = pulse[1]
171 rise = pulse[2]
172 fall = pulse[3]
173 start = pos - rise
174 stop = pos + fall
175 signal[start:pos] += np.linspace(0., height, rise)
176 signal[pos:stop] += np.linspace(height, 0. , fall)
177 if 'spike' in self.options:
178 for spike in self.spikes:
179 signal[spike[0]] += spike[1]
180 if 'csv' in self.options:
181 for csv in self.csvs:
182 amplitude = csv[1]
183 time = csv[0]
184 csv_data = self.csv_data.copy()
185 #scale
186 csv_data *= amplitude
187 # add shifted
188 print 'bumm', len(csv_data)
189 print csv_data.shape
190 print signal[time:time+len(csv_data)].shape
191 signal[time:time+len(csv_data)] += csv_data
192
193 # add noise
194 signal += + np.random.normal(0.0,self.sigma, signal.shape)
195 return signal
196
197 def __str__(self):
198 s = self.name + '\n'
199 s += 'possible options and parameters\n'
200 s += ' * len: number of samples (100)\n'
201 s += ' * noise: sigma (1)\n'
202 s += ' * bsl: level (-0.5)\n'
203 s += ' * step: height, start, end\n'
204 s += ' * triangle: pos height risingedge, fallingedge [pos height ...]\n'
205 s += ' * spike: pos height [pos height ...]\n'
206 s += ' * csv: pos height [pos height ...]\n'
207
208 s += 'current options are:\n'
209 for key in self.options.keys():
210 s += key + ':' + str(self.options[key]) + '\n'
211 return s
212
213
214# Helper function to parse signalname and create a dictionary
215# dictionary layout :
216# key : string
217# value : [list of parameters]
218def make_options_from_str(signalname):
219 options = {}
220 for word in (signalname.lower()).split():
221 if word.isalpha():
222 current_key = word
223 options[current_key] = []
224# if word.isdigit():
225 else:
226 options[current_key].append(word)
227# else:
228# print '-nothing'
229 return options
230
231if __name__ == '__main__':
232 from plotters import Plotter
233 myGenerator = SignalGenerator('len 400 noise 0.3 bsl -2.5 triangle 50 10.2 10 100 65 10 150 20 spike 100 50. 20 50 21 49')
234 sig = myGenerator()
235 print myGenerator
236
237 p = Plotter('generator test')
238 p(sig)
239
240 anothergen = SignalGeneratorCSV('PulseTemplate_PointSet_0.csv',
241 'len 1000 noise 0.4 bsl -2.0 csv 300 1 60 2 650 1 spike 110 50')
242 sig2 = anothergen()
243 print anothergen
244
245 pp = Plotter('CSV Gen Test')
246 pp(sig2)
247
248 raw_input('any key to quit')
Note: See TracBrowser for help on using the repository browser.