Mercurial > hg > ltpda
comparison m-toolbox/classes/@ao/fromWaveform.m @ 0:f0afece42f48
Import.
author | Daniele Nicolodi <nicolodi@science.unitn.it> |
---|---|
date | Wed, 23 Nov 2011 19:22:13 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:f0afece42f48 |
---|---|
1 % FROMWAVEFORM Construct an ao from a waveform | |
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
3 % | |
4 % FUNCTION: fromWaveform | |
5 % | |
6 % DESCRIPTION: Construct an ao from a waveform | |
7 % | |
8 % CALL: a = fromWaveform(pl) | |
9 % | |
10 % PARAMETER: pl: Parameter list object | |
11 % | |
12 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
13 function a = fromWaveform(a, pli, callerIsMethod) | |
14 | |
15 VERSION = '$Id: fromWaveform.m,v 1.44 2011/08/15 10:42:38 hewitson Exp $'; | |
16 | |
17 if callerIsMethod | |
18 % do nothing | |
19 else | |
20 % get AO info | |
21 ii = ao.getInfo('ao', 'From Waveform'); | |
22 | |
23 % Set the method version string in the minfo object | |
24 ii.setMversion([VERSION '-->' ii.mversion]); | |
25 end | |
26 | |
27 if callerIsMethod | |
28 pl = pli; | |
29 else | |
30 % Combine input plist with default values | |
31 pl = applyDefaults(ii.plists, pli); | |
32 end | |
33 | |
34 nsecs = find(pl, 'nsecs'); | |
35 fs = find(pl, 'fs'); | |
36 t0 = find(pl, 't0'); | |
37 | |
38 waveform = find(pl, 'waveform'); | |
39 if numel(nsecs) == 1 | |
40 if isempty(nsecs) || nsecs == 0 | |
41 error('### Please provide ''Nsecs'' for waveform constructor.'); | |
42 end | |
43 end | |
44 if isempty(fs) || fs == 0 | |
45 error('### Please provide ''fs'' for waveform constructor.'); | |
46 end | |
47 | |
48 % Override defaults | |
49 if isempty(t0) | |
50 t0 = time(0); | |
51 elseif ischar(t0) || isnumeric(t0) | |
52 t0 = time(t0); | |
53 end | |
54 if isempty(find(pl, 'name')) | |
55 pl.pset('Name', waveform); | |
56 end | |
57 | |
58 | |
59 switch lower(waveform) | |
60 %------------ Sine Wave | |
61 case {'sine wave', 'sinewave', 'sine-wave', 'sine'} | |
62 ampl = find(pl, 'A'); | |
63 freq = find(pl, 'f'); | |
64 phi = find(pl, 'phi'); | |
65 Toff = find(pl, 'Toff'); | |
66 gaps = find(pl, 'gaps'); | |
67 | |
68 % If Toff is a time-string or a time object then convert this time | |
69 % into a number of seconds depending to T0 | |
70 if ischar(Toff) || iscell(Toff) || isa(Toff, 'plist') | |
71 | |
72 % If the t0 is the default value then set it to the first value of Toff | |
73 if strcmpi(find(pl, 't0'), '1970-01-01 00:00:00.000') | |
74 t0 = time(Toff(1)); | |
75 end | |
76 | |
77 newToff = []; | |
78 if ischar(Toff) | |
79 newToff = (time(Toff).utc_epoch_milli - t0.utc_epoch_milli) /1e3; | |
80 else | |
81 Toff = time(Toff); | |
82 for zz = 1:numel(Toff) | |
83 newToff = [newToff (Toff(zz).utc_epoch_milli - t0.utc_epoch_milli)/1e3]; | |
84 end | |
85 end | |
86 | |
87 Toff = newToff; | |
88 end | |
89 | |
90 % The user specified gaps instead of offsets. | |
91 % (The gap is before the signal starts) | |
92 if isempty(pli.find('Toff')) && ~isempty(gaps) | |
93 Toff(1) = gaps(1); | |
94 for ww = 2:numel(nsecs) | |
95 Toff(ww) = sum(gaps(1:ww)) + sum(nsecs(1:ww-1)); | |
96 end | |
97 end | |
98 | |
99 % If the number of Amplitude, frequency and phase are not the same | |
100 % then duplicate the last specified value. | |
101 max_waves = max([numel(ampl), numel(freq), numel(phi), numel(nsecs), numel(Toff)]); | |
102 | |
103 ampl = [ampl, repmat(ampl(end), 1, max_waves - numel(ampl))]; | |
104 freq = [freq, repmat(freq(end), 1, max_waves - numel(freq))]; | |
105 phi = [phi, repmat(phi(end), 1, max_waves - numel(phi))]; | |
106 nsecs = [nsecs, repmat(nsecs(end), 1, max_waves - numel(nsecs))]; | |
107 Toff = [Toff, repmat(Toff(end), 1, max_waves - numel(Toff))]; | |
108 | |
109 %%%%%%%%%%%%%%%%%%%% add different sine waves with time offset %%%%%%%%%%%%%%%%%%%% | |
110 | |
111 maxValues = 0; | |
112 % Predefine the total result with zeros | |
113 for kk = 1:numel(Toff) | |
114 values = (Toff(kk) + nsecs(kk)) * fs; | |
115 if maxValues < values | |
116 maxValues = values; | |
117 end | |
118 end | |
119 total = zeros(maxValues, 1); | |
120 | |
121 % Over all sine waves | |
122 for kk = 1:numel(Toff) | |
123 | |
124 % Compute the y-values of each sine wave | |
125 t = 0 : 1/fs : nsecs(kk)-1/fs; | |
126 y = ampl(kk) * sin(2*pi*freq(kk)*t + phi(kk)); | |
127 | |
128 % Add the computed values to the total result | |
129 begT = floor(Toff(kk)*fs); | |
130 endT = begT + nsecs(kk)*fs; | |
131 idx = begT+1:endT; | |
132 | |
133 total(idx) = total(idx) + y.'; | |
134 | |
135 end | |
136 | |
137 if isempty(total) | |
138 error('### You have defined a sine-wave with the length zero.'); | |
139 end | |
140 | |
141 ts = tsdata(total, fs); | |
142 ts.setXunits(find(pl, 'xunits')); | |
143 ts.setYunits(find(pl, 'yunits')); | |
144 ts.setT0(t0); | |
145 | |
146 % Make an analysis object | |
147 a.data = ts; | |
148 if callerIsMethod | |
149 % do nothing | |
150 % At the moment, we keep adding the history. | |
151 % There might be something we need for rebuilding, like RAND_STREAM | |
152 a.addHistory(ii, pl, [], []); | |
153 else | |
154 % Add history | |
155 a.addHistory(ii, pl, [], []); | |
156 end | |
157 | |
158 % Set some procedure information | |
159 a.procinfo = plist('start times', time(t0.utc_epoch_milli/1e3 + Toff)); | |
160 | |
161 % Set the object properties from the plist | |
162 a.setObjectProperties(pl); | |
163 | |
164 % This is a special case where we don't evaluate a string function | |
165 % but build the values according to the recipe. As such we have | |
166 % already handled the setting of properties and history and we can | |
167 % return here. | |
168 return | |
169 | |
170 case 'noise' | |
171 ntype = find(pl, 'type'); | |
172 pl.getSetRandState(); | |
173 | |
174 if isempty(ntype) | |
175 ntype = 'Normal'; | |
176 end | |
177 sigma = find(pl, 'sigma'); | |
178 if isempty(sigma) | |
179 sigma = 1; | |
180 end | |
181 | |
182 switch lower(ntype) | |
183 case 'normal' | |
184 tsfcn = sprintf('%g.*randn(size(t))', sigma); | |
185 | |
186 case 'uniform' | |
187 tsfcn = sprintf('%g.*rand(size(t))', sigma); | |
188 | |
189 end | |
190 %------------ Chirp | |
191 case 'chirp' | |
192 f0 = find(pl, 'f0'); | |
193 fe = find(pl, 'f1'); | |
194 te = find(pl, 't1'); | |
195 if isempty(f0) | |
196 f0 = 0; | |
197 end | |
198 if isempty(fe) | |
199 fe = fs/2; | |
200 end | |
201 if isempty(te) | |
202 te = nsecs; | |
203 end | |
204 tsfcn = sprintf('chirp(t,%g,%g,%g)', f0, fe, te); | |
205 %------------ Gaussian pulse | |
206 case {'gaussian pulse', 'gaussian-pulse'} | |
207 fc = find(pl, 'f0'); | |
208 bw = find(pl, 'bw'); | |
209 if isempty(fc) | |
210 fc = 1; | |
211 end | |
212 if isempty(bw) | |
213 bw = fs/2; | |
214 end | |
215 tsfcn = sprintf('gauspuls(t,%g,%g)', fc, bw); | |
216 case {'square wave', 'squarewave', 'square-wave', 'square'} | |
217 freq = find(pl, 'f'); | |
218 duty = find(pl, 'duty'); | |
219 if isempty(freq) | |
220 freq = 1; | |
221 end | |
222 if isempty(duty) | |
223 duty = 50; | |
224 end | |
225 tsfcn = sprintf('square(2*pi*%g*t,%g)', freq, duty); | |
226 case {'saw tooth', 'sawtooth', 'saw-tooth', 'saw'} | |
227 freq = find(pl, 'f'); | |
228 width = find(pl, 'width'); | |
229 if isempty(freq) | |
230 freq = 1; | |
231 end | |
232 if isempty(width) | |
233 width = 0.5; | |
234 end | |
235 tsfcn = sprintf('sawtooth(2*pi*%g*t,%g)', freq, width); | |
236 otherwise | |
237 error('### Unknown waveform type [%s]', waveform); | |
238 end | |
239 | |
240 % construct tsdata | |
241 t = 0 : 1/fs : nsecs-1/fs; % t = linspace(0, nsecs(kk)-1/fs, nsecs(kk)*fs); | |
242 % make y data | |
243 y = eval([tsfcn ';']); | |
244 | |
245 ts = tsdata(t, y'); | |
246 ts.setT0(t0); | |
247 ts.setXunits(find(pl, 'xunits')); | |
248 ts.setYunits(find(pl, 'yunits')); | |
249 | |
250 % Make an analysis object | |
251 a.data = ts; | |
252 | |
253 if callerIsMethod | |
254 % do nothing | |
255 % At the moment, we keep adding the history. | |
256 % There might be something we need for rebuilding, like RAND_STREAM | |
257 a.addHistory(ii, pl, [], []); | |
258 else | |
259 % Add history | |
260 a.addHistory(ii, pl, [], []); | |
261 end | |
262 | |
263 % Set the object properties from the plist | |
264 a.setObjectProperties(pl); | |
265 | |
266 end | |
267 |