Mercurial > hg > ltpda
comparison m-toolbox/classes/@ao/timeaverage.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 % TIMEAVERAGE Averages time series intervals | |
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
3 % | |
4 % DESCRIPTION: Averages time series intervals and return a reduced time | |
5 % series where each point represents the average of a stretch of data. | |
6 % Despite the name this method can perform some different operations on the | |
7 % data stretches or apply a user supplied function. Different functions can | |
8 % be applied to X and Y data. | |
9 % | |
10 % CALL: BS = timeaverage(A1, A2, A3, ..., PL) | |
11 % | |
12 % INPUTS: AN - time series AOs | |
13 % PL - parameters list | |
14 % | |
15 % OUTPUTS: BS - array of AOs | |
16 % | |
17 % <a href="matlab:utils.helper.displayMethodInfo('ao', 'timeaverage')">Parameters Description</a> | |
18 % | |
19 % EXAMPLES: | |
20 % | |
21 % >> times = [ 0 100 200 300 400 500 ] | |
22 % >> timeaverage(a, plist('times', times)) | |
23 % >> timeaverage(a, plist('start', 0, 'duration', 100, 'decay', 10, 'repetitions', 3)) | |
24 % >> timeaverage(a, plist('times', times, 'function', 'center')) | |
25 % >> timeaverage(a, plist('times', times, 'function', @mean)) | |
26 % >> timeaverage(a, plist('times', times, 'xfunction', @min, 'yfunction', @mean)) | |
27 % | |
28 % NOTES: The intervals are defined as ti <= x < te where ti is the start | |
29 % time and te is the end time of each interval. If not specified the TIMES | |
30 % vector is constructed from other parameters using the following schema | |
31 % repeated accordingly a number of times specified with the REPETITIONS | |
32 % parameter. | |
33 % | |
34 % settling duration decay settling duration | |
35 % |------------|##############|---------|------------|##############|--- | |
36 % START | |
37 % | |
38 % | |
39 % VERSION: $Id: timeaverage.m,v 1.10 2011/05/16 09:31:35 mauro Exp $ | |
40 % | |
41 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
42 | |
43 function varargout = timeaverage(varargin) | |
44 | |
45 % check if this is a call for parameters | |
46 if utils.helper.isinfocall(varargin{:}) | |
47 varargout{1} = getInfo(varargin{3}); | |
48 return | |
49 end | |
50 | |
51 import utils.const.* | |
52 utils.helper.msg(msg.PROC3, 'running %s/%s', mfilename('class'), mfilename); | |
53 | |
54 % collect input variable names | |
55 in_names = cell(size(varargin)); | |
56 for ii = 1:nargin,in_names{ii} = inputname(ii);end | |
57 | |
58 % collect all AOs and plists | |
59 [as, ao_invars] = utils.helper.collect_objects(varargin(:), 'ao', in_names); | |
60 pl = utils.helper.collect_objects(varargin(:), 'plist', in_names); | |
61 | |
62 % decide on a deep copy or a modify | |
63 bs = copy(as, nargout); | |
64 | |
65 % accept spaces dashes or underscores | |
66 pl = fixpnames(pl); | |
67 | |
68 % combine plists | |
69 pl = combine(pl, getDefaultPlist()); | |
70 | |
71 % splitting by time takes the precedence | |
72 times = find(pl, 'times'); | |
73 | |
74 % otherwise construct a times vector based on other parameters | |
75 if isempty(times) | |
76 start = find(pl, 'start', find(pl, 'start time')); | |
77 repeat = find(pl, 'repetitions'); | |
78 duration = find(pl, 'duration'); | |
79 settling = find(pl, 'settling', find(pl, 'settling time')); | |
80 decay = find(pl, 'decay', find(pl, 'decay time')); | |
81 | |
82 times = zeros(repeat*2, 1); | |
83 for kk = 1:repeat | |
84 times(2*kk-1) = start + settling*kk + duration*(kk-1) + decay*(kk-1); | |
85 times(2*kk) = start + settling*kk + duration*kk + decay*(kk-1); | |
86 end | |
87 end | |
88 | |
89 % check that the times vector as the right dimensions | |
90 if mod(numel(times), 2) | |
91 error('### times defines times intervals with an even number of points'); | |
92 end | |
93 | |
94 % select which functions to apply to the data stretches | |
95 method = lower(find(pl, 'method')); | |
96 funct = find(pl, 'function'); | |
97 if isempty(funct) | |
98 funct = method; | |
99 end | |
100 xfunct = find(pl, 'xfunction', funct); | |
101 yfunct = find(pl, 'yfunction', funct); | |
102 if isempty(xfunct) | |
103 xfunct = funct; | |
104 end | |
105 if isempty(yfunct) | |
106 yfunct = funct; | |
107 end | |
108 | |
109 % loop over input AOs | |
110 for jj = 1:numel(bs) | |
111 | |
112 % check input data | |
113 if ~isa(bs(jj).data, 'tsdata') | |
114 warning('LTPDA:isNotTsdata', '!!! %s is not a tsdata AO and will be ingnored', bs(jj).name); | |
115 continue; | |
116 end | |
117 | |
118 [xmean, ymean, dy] = split_and_apply(bs(jj).x, bs(jj).y, times, xfunct, yfunct); | |
119 | |
120 % assign values | |
121 bs(jj).setXY(xmean, ymean); | |
122 bs(jj).setDy(dy); | |
123 | |
124 % set name | |
125 bs(jj).name = sprintf('%s(%s)', mfilename, ao_invars{jj}); | |
126 % add history | |
127 bs(jj).addHistory(getInfo('None'), pl, ao_invars(jj), bs(jj).hist); | |
128 | |
129 end % loop over analysis objects | |
130 | |
131 % set output | |
132 if nargout == numel(bs) | |
133 % list of outputs | |
134 for ii = 1:numel(bs) | |
135 varargout{ii} = bs(ii); | |
136 end | |
137 else | |
138 % single output | |
139 varargout{1} = bs; | |
140 end | |
141 end | |
142 | |
143 | |
144 function ii = getInfo(varargin) | |
145 if nargin == 1 && strcmpi(varargin{1}, 'None') | |
146 sets = {}; | |
147 pl = []; | |
148 else | |
149 sets = {'Default'}; | |
150 pl = getDefaultPlist; | |
151 end | |
152 % build info object | |
153 ii = minfo(mfilename, 'ao', 'ltpda', utils.const.categories.sigproc, '$Id: timeaverage.m,v 1.10 2011/05/16 09:31:35 mauro Exp $', sets, pl); | |
154 % set the default property of the method as modifier or not | |
155 ii.setModifier(true); | |
156 % set the minumum number of inputs and outputs for the block | |
157 ii.setArgsmin(1); | |
158 ii.setOutmin(1); | |
159 end | |
160 | |
161 | |
162 function plout = getDefaultPlist() | |
163 persistent pl; | |
164 if exist('pl', 'var')==0 || isempty(pl) | |
165 pl = buildplist(); | |
166 end | |
167 plout = pl; | |
168 end | |
169 | |
170 function pl = buildplist() | |
171 pl = plist; | |
172 | |
173 % method | |
174 p = param({'method','Reduction method to apply to data stretches.'}, ... | |
175 {1, {'MEAN', 'MEDIAN', 'MAX', 'MIN', 'RMS', 'CENTER'}, paramValue.SINGLE}); | |
176 pl.append(p); | |
177 | |
178 % function | |
179 p = param({'function', ['Function to apply to data stretches. It can be' ... | |
180 ' a function name or a function handle to a function that accepts'... | |
181 ' a vector and returns a scalar.']}, paramValue.EMPTY_DOUBLE); | |
182 pl.append(p); | |
183 | |
184 % x function | |
185 p = param({'xfunction', ['Function to apply to X data stretches. It can be' ... | |
186 ' a function name or a function handle to a function that accepts'... | |
187 ' a vector and returns a scalar.']}, paramValue.EMPTY_DOUBLE); | |
188 pl.append(p); | |
189 | |
190 % y function | |
191 p = param({'yfunction', ['Function to apply to Y data stretches. It can be' ... | |
192 ' a function name or a function handle to a function that accepts'... | |
193 ' a vector and returns a scalar.']}, paramValue.EMPTY_DOUBLE); | |
194 pl.append(p); | |
195 | |
196 % times | |
197 p = param({'times', 'An array of start-stop times to split by.'}, paramValue.DOUBLE_VALUE([])); | |
198 pl.append(p); | |
199 | |
200 % start time | |
201 p = param({'start time', 'Start time of the measurement.'}, paramValue.DOUBLE_VALUE(0)); | |
202 pl.append(p); | |
203 | |
204 % duration | |
205 p = param({'duration', 'Duration of each cicle.'}, paramValue.DOUBLE_VALUE(0)); | |
206 pl.append(p); | |
207 | |
208 % repetitions | |
209 p = param({'repetitions', 'Number of cycles.'}, paramValue.DOUBLE_VALUE(1)); | |
210 pl.append(p); | |
211 | |
212 % settling time | |
213 p = param({'settling time', 'Settling time in each cicle.'}, paramValue.DOUBLE_VALUE(0)); | |
214 pl.append(p); | |
215 | |
216 % decay time | |
217 p = param({'decay time', 'Decay time in each cicle.'}, paramValue.DOUBLE_VALUE(0)); | |
218 pl.append(p); | |
219 | |
220 end | |
221 | |
222 | |
223 function pl = fixpnames(pl) | |
224 % replace underscores and dashes in parameters names with spaces | |
225 if isa(pl, 'plist') | |
226 for ii = 1:pl.nparams | |
227 pl.params(ii).setKey(strrep(strrep(pl.params(ii).key, '_', ' '), '-', ' ')); | |
228 end | |
229 end | |
230 end | |
231 | |
232 | |
233 function xmean = center(x) %#ok<DEFNU> | |
234 % computes the center of an interval defined by | |
235 % the minimum and maximum values in an array | |
236 xmean = mean([min(x) max(x)]); | |
237 end | |
238 | |
239 | |
240 function [xmean, ymean, dy] = split_and_apply(x, y, times, xfunct, yfunct) | |
241 | |
242 % number of intervals | |
243 nint = numel(times) / 2; | |
244 | |
245 xmean = zeros(nint, 1); | |
246 ymean = zeros(nint, 1); | |
247 | |
248 % for the mean we are able to compute uncertainty too | |
249 if ischar(yfunct) && strcmp(yfunct, 'mean') | |
250 dy = zeros(nint, 1); | |
251 else | |
252 dy = []; | |
253 end | |
254 | |
255 % loop over the intervals | |
256 for kk = 1:nint | |
257 | |
258 % create index of the interval | |
259 is = times(2*kk-1); | |
260 ie = times(2*kk); | |
261 idx = x >= is & x < ie; | |
262 | |
263 % apply functions to interval | |
264 xmean(kk) = feval(xfunct, x(idx)); | |
265 ymean(kk) = feval(yfunct, y(idx)); | |
266 | |
267 if ~isempty(dy) | |
268 % compute uncertainty as the standard deviation of the mean | |
269 dy(kk) = std(y(idx)) / sqrt(length(x(idx))); | |
270 end | |
271 | |
272 end | |
273 end |