diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/m-toolbox/classes/@ao/timeaverage.m	Wed Nov 23 19:22:13 2011 +0100
@@ -0,0 +1,273 @@
+% TIMEAVERAGE Averages time series intervals
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DESCRIPTION: Averages time series intervals and return a reduced time
+% series where each point represents the average of a stretch of data.
+% Despite the name this method can perform some different operations on the
+% data stretches or apply a user supplied function. Different functions can
+% be applied to X and Y data.
+%
+% CALL:        BS = timeaverage(A1, A2, A3, ..., PL)
+%
+% INPUTS:      AN   - time series AOs
+%              PL   - parameters list
+%
+% OUTPUTS:     BS   - array of AOs
+% 
+% <a href="matlab:utils.helper.displayMethodInfo('ao', 'timeaverage')">Parameters Description</a>
+%
+% EXAMPLES:
+% 
+% >> times = [ 0 100 200 300 400 500 ]
+% >> timeaverage(a, plist('times', times))
+% >> timeaverage(a, plist('start', 0, 'duration', 100, 'decay', 10, 'repetitions', 3))
+% >> timeaverage(a, plist('times', times, 'function', 'center'))
+% >> timeaverage(a, plist('times', times, 'function', @mean))
+% >> timeaverage(a, plist('times', times, 'xfunction', @min, 'yfunction', @mean))
+%
+% NOTES: The intervals are defined as ti <= x < te where ti is the start
+% time and te is the end time of each interval. If not specified the TIMES
+% vector is constructed from other parameters using the following schema
+% repeated accordingly a number of times specified with the REPETITIONS
+% parameter.
+%
+%       settling      duration      decay     settling      duration
+%    |------------|##############|---------|------------|##############|---
+%  START
+%
+%
+% VERSION: $Id: timeaverage.m,v 1.10 2011/05/16 09:31:35 mauro Exp $
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+function varargout = timeaverage(varargin)
+  
+  % check if this is a call for parameters
+  if utils.helper.isinfocall(varargin{:})
+    varargout{1} = getInfo(varargin{3});
+    return
+  end
+  
+  import utils.const.*
+  utils.helper.msg(msg.PROC3, 'running %s/%s', mfilename('class'), mfilename);
+  
+  % collect input variable names
+  in_names = cell(size(varargin));
+  for ii = 1:nargin,in_names{ii} = inputname(ii);end
+  
+  % collect all AOs and plists
+  [as, ao_invars] = utils.helper.collect_objects(varargin(:), 'ao', in_names);
+  pl              = utils.helper.collect_objects(varargin(:), 'plist', in_names);
+  
+  % decide on a deep copy or a modify
+  bs = copy(as, nargout);
+  
+  % accept spaces dashes or underscores
+  pl = fixpnames(pl);
+  
+  % combine plists
+  pl = combine(pl, getDefaultPlist());
+  
+  % splitting by time takes the precedence
+  times = find(pl, 'times');
+  
+  % otherwise construct a times vector based on other parameters
+  if isempty(times)
+    start    = find(pl, 'start', find(pl, 'start time'));
+    repeat   = find(pl, 'repetitions');
+    duration = find(pl, 'duration');
+    settling = find(pl, 'settling', find(pl, 'settling time'));
+    decay    = find(pl, 'decay', find(pl, 'decay time'));
+    
+    times = zeros(repeat*2, 1);
+    for kk = 1:repeat
+      times(2*kk-1)   = start + settling*kk + duration*(kk-1) + decay*(kk-1);
+      times(2*kk) = start + settling*kk + duration*kk + decay*(kk-1);
+    end
+  end
+  
+  % check that the times vector as the right dimensions
+  if mod(numel(times), 2)
+    error('### times defines times intervals with an even number of points');
+  end
+  
+  % select which functions to apply to the data stretches
+  method = lower(find(pl, 'method'));
+  funct  = find(pl, 'function');
+  if isempty(funct)
+    funct = method;
+  end
+  xfunct = find(pl, 'xfunction', funct);
+  yfunct = find(pl, 'yfunction', funct);
+  if isempty(xfunct)
+    xfunct = funct;
+  end
+  if isempty(yfunct)
+    yfunct = funct;
+  end
+  
+  % loop over input AOs
+  for jj = 1:numel(bs)
+    
+    % check input data
+    if ~isa(bs(jj).data, 'tsdata')
+      warning('LTPDA:isNotTsdata', '!!! %s is not a tsdata AO and will be ingnored', bs(jj).name);
+      continue;
+    end
+    
+    [xmean, ymean, dy] = split_and_apply(bs(jj).x, bs(jj).y, times, xfunct, yfunct);
+    
+    % assign values
+    bs(jj).setXY(xmean, ymean);
+    bs(jj).setDy(dy);
+    
+    % set name
+    bs(jj).name = sprintf('%s(%s)', mfilename, ao_invars{jj});
+    % add history
+    bs(jj).addHistory(getInfo('None'), pl, ao_invars(jj), bs(jj).hist);
+    
+  end % loop over analysis objects
+  
+  % set output
+  if nargout == numel(bs)
+    % list of outputs
+    for ii = 1:numel(bs)
+      varargout{ii} = bs(ii);
+    end
+  else
+    % single output
+    varargout{1} = bs;
+  end
+end
+
+
+function ii = getInfo(varargin)
+  if nargin == 1 && strcmpi(varargin{1}, 'None')
+    sets = {};
+    pl   = [];
+  else
+    sets = {'Default'};
+    pl   = getDefaultPlist;
+  end
+  % build info object
+  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);
+  % set the default property of the method as modifier or not
+  ii.setModifier(true);
+  % set the minumum number of inputs and outputs for the block
+  ii.setArgsmin(1);
+  ii.setOutmin(1);
+end
+
+
+function plout = getDefaultPlist()
+  persistent pl;  
+  if exist('pl', 'var')==0 || isempty(pl)
+    pl = buildplist();
+  end
+  plout = pl;  
+end
+
+function pl = buildplist()
+  pl = plist;
+  
+  % method
+  p = param({'method','Reduction method to apply to data stretches.'}, ...
+    {1, {'MEAN', 'MEDIAN', 'MAX', 'MIN', 'RMS', 'CENTER'}, paramValue.SINGLE});
+  pl.append(p);
+  
+  % function
+  p = param({'function', ['Function to apply to data stretches. It can be' ...
+    ' a function name or a function handle to a function that accepts'...
+    ' a vector and returns a scalar.']}, paramValue.EMPTY_DOUBLE);
+  pl.append(p);
+  
+  % x function
+  p = param({'xfunction', ['Function to apply to X data stretches. It can be' ...
+    ' a function name or a function handle to a function that accepts'...
+    ' a vector and returns a scalar.']}, paramValue.EMPTY_DOUBLE);
+  pl.append(p);
+  
+  % y function
+  p = param({'yfunction', ['Function to apply to Y data stretches. It can be' ...
+    ' a function name or a function handle to a function that accepts'...
+    ' a vector and returns a scalar.']}, paramValue.EMPTY_DOUBLE);
+  pl.append(p);
+  
+  % times
+  p = param({'times', 'An array of start-stop times to split by.'}, paramValue.DOUBLE_VALUE([]));
+  pl.append(p);
+  
+  % start time
+  p = param({'start time', 'Start time of the measurement.'}, paramValue.DOUBLE_VALUE(0));
+  pl.append(p);
+  
+  % duration
+  p = param({'duration', 'Duration of each cicle.'}, paramValue.DOUBLE_VALUE(0));
+  pl.append(p);
+  
+  % repetitions
+  p = param({'repetitions', 'Number of cycles.'}, paramValue.DOUBLE_VALUE(1));
+  pl.append(p);
+  
+  % settling time
+  p = param({'settling time', 'Settling time in each cicle.'}, paramValue.DOUBLE_VALUE(0));
+  pl.append(p);            
+      
+  % decay time
+  p = param({'decay time', 'Decay time in each cicle.'}, paramValue.DOUBLE_VALUE(0));
+  pl.append(p);            
+  
+end
+
+
+function pl = fixpnames(pl)
+  % replace underscores and dashes in parameters names with spaces
+  if isa(pl, 'plist')
+    for ii = 1:pl.nparams
+      pl.params(ii).setKey(strrep(strrep(pl.params(ii).key, '_', ' '), '-', ' '));
+    end
+  end
+end
+
+
+function xmean = center(x) %#ok<DEFNU>
+  % computes the center of an interval defined by
+  % the minimum and maximum values in an array
+  xmean = mean([min(x) max(x)]);
+end
+
+
+function [xmean, ymean, dy] = split_and_apply(x, y, times, xfunct, yfunct)
+  
+  % number of intervals
+  nint = numel(times) / 2;
+  
+  xmean = zeros(nint, 1);
+  ymean = zeros(nint, 1);
+  
+  % for the mean we are able to compute uncertainty too
+  if ischar(yfunct) && strcmp(yfunct, 'mean')
+    dy = zeros(nint, 1);
+  else
+    dy = [];
+  end
+  
+  % loop over the intervals
+  for kk = 1:nint
+    
+    % create index of the interval
+    is = times(2*kk-1);
+    ie = times(2*kk);
+    idx = x >= is & x < ie;
+    
+    % apply functions to interval
+    xmean(kk) = feval(xfunct, x(idx));
+    ymean(kk) = feval(yfunct, y(idx));
+    
+    if ~isempty(dy)
+      % compute uncertainty as the standard deviation of the mean
+      dy(kk) = std(y(idx)) / sqrt(length(x(idx)));
+    end
+    
+  end  
+end