diff m-toolbox/classes/@ao/lxspec.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/lxspec.m	Wed Nov 23 19:22:13 2011 +0100
@@ -0,0 +1,208 @@
+% LXSPEC performs log-scale cross-spectral analysis of various forms.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DESCRIPTION: LXSPEC performs log-scale cross-spectral analysis of various forms.
+%              The function is a helper function for various higher level
+%              functions. It is meant to be called from other functions
+%              (e.g., ltfe).
+%
+% CALL:       b = lxspec(a, pl, method, iALGO, iVER, invars);
+%
+% INPUTS:     a      - vector of input AOs
+%             pl     - input parameter list
+%             method - one of
+%                       'cpsd'     - compute cross-spectral density
+%                       'tfe'      - estimate transfer function between inputs
+%                       'mscohere' - estimate magnitude-squared cross-coherence
+%                       'cohere'   - estimate complex cross-coherence
+%             mi     - minfo object for calling method
+%             invars - invars variable from the calling higher level script
+%
+% OUTPUTS:    b  - output AO
+%
+% VERSION:    $Id: lxspec.m,v 1.44 2011/04/05 08:12:40 mauro Exp $
+%
+% HISTORY:    16-05-2008 M Hewitson
+%                Creation
+%
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+function varargout = lxspec(varargin)
+  
+  import utils.const.*
+  
+  % unpack inputs
+  as       = varargin{1};
+  pl       = varargin{2};
+  method   = varargin{3};
+  mi       = varargin{4};
+  invars   = varargin{5};
+  
+  VERSION  = '$Id: lxspec.m,v 1.44 2011/04/05 08:12:40 mauro Exp $';
+  % Set the method version string in the minfo object
+  mi.setMversion([VERSION '-->' mi.mversion]);
+  
+  %----------------- Select all AOs with time-series data
+  tsao = [];
+  for ll=1:numel(as)
+    if isa(as(ll).data, 'tsdata')
+      tsao = [tsao as(ll)];
+    else
+      warning('### xspec requires tsdata (time-series) inputs. Skipping AO %s. \nREMARK: The output doesn''t contain this AO', invars{ll});
+    end
+  end
+  % Check if there are some AOs left
+  if numel(tsao) ~= 2
+    error('### LXSPEC needs two time-series AOs.');
+  end
+    
+  %----------------- Gather the input history objects
+  inhists = [tsao(:).hist];
+  
+  %----------------- Check the time range.
+  time_range = mfind(pl, 'split', 'times');
+  for ll=1:numel(tsao)
+    if ~isempty(time_range)
+      switch class(time_range)
+        case 'double'
+          tsao(ll) = split(tsao(ll), plist(...
+            'times', time_range));
+        case 'timespan'
+          tsao(ll) = split(tsao(ll), plist(...
+            'timespan', time_range));
+        case 'time'
+          tsao(ll) = split(tsao(ll), plist(...
+            'start_time', time_range(1), ...
+            'end_time', time_range(2)));
+        case 'cell'
+          tsao(ll) = split(tsao(ll), plist(...
+            'start_time', time_range{1}, ...
+            'end_time', time_range{2}));
+        otherwise
+      end
+    end
+    if tsao(ll).len <= 0
+      error('### The object is empty! Please revise your settings ...');
+    end
+  end
+  
+  copies = zeros(size(tsao));
+  
+  %----------------- Resample all AOs
+  fsmax = ao.findFsMax(tsao);
+  fspl  = plist(param('fsout', fsmax));
+  for ll = 1:numel(tsao)
+    % Check Fs
+    if tsao(ll).data.fs ~= fsmax
+      utils.helper.msg(msg.PROC2, 'resampling AO %s to %f Hz', tsao(ll).name, fsmax);
+      % Make a deep copy so we don't
+      % affect the original input data
+      tsao(ll) = copy(tsao(ll), 1);
+      copies(ll) = 1;
+      tsao(ll).resample(fspl);
+    end
+  end
+  
+  %----------------- Truncate all vectors
+  % Get shortest vector
+  lmin = ao.findShortestVector(tsao);
+  nsecs = lmin / fsmax;
+  for ll = 1:numel(tsao)
+    if len(tsao(ll)) ~= lmin
+      utils.helper.msg(msg.PROC1, 'truncating AO %s to %d secs', tsao(ll).name, nsecs);
+      % do we already have a copy?
+      if ~copies(ll)
+        % Make a deep copy so we don't
+        % affect the original input data
+        tsao(ll) = copy(tsao(ll), 1);
+        copies(ll) = 1;
+      end
+      tsao(ll).select(1:lmin);
+    end
+  end
+  
+  %----------------- Build signal Matrix
+  N     = len(tsao(1)); % length of first signal
+  iS    = zeros(numel(tsao), N);
+  for jj = 1:numel(tsao)
+    iS(jj,:) = tsao(jj).data.getY;
+  end
+  
+  %----------------- check input parameters
+  pl = utils.helper.process_spectral_options(pl, 'log');
+  
+  % Desired number of averages
+  Kdes = find(pl, 'Kdes');
+  % num desired spectral frequencies
+  Jdes = find(pl, 'Jdes');
+  % Minimum segment length
+  Lmin = find(pl, 'Lmin');
+  % Window function
+  Win = find(pl, 'Win');
+  % Overlap
+  Nolap = find(pl, 'Olap')/100;
+  % Order of detrending
+  Order = find(pl, 'Order');
+  
+  %----------------- Get frequency vector
+  [f, r, m, L, K] = ao.ltf_plan(lmin, fsmax, Nolap, 1, Lmin, Jdes, Kdes);
+  
+  %----------------- compute TF Estimates
+  [Txy dev]= ao.mltfe(iS, f, r, m, L,K,fsmax, Win, Order, Nolap*100, Lmin, method);
+  
+  % Keep the data shape of the first AO
+  if size(tsao(1).data.y, 1) == 1
+    f   = f.';
+    Txy = Txy.';
+    dev = dev.';
+  end
+  
+  %----------------- Build output Matrix of AOs
+  
+  % create new output fsdata
+  fsd = fsdata(f, Txy, fsmax);
+  fsd.setXunits('Hz');
+  switch lower(method)
+    case 'tfe'
+      fsd.setYunits(tsao(2).data.yunits / tsao(1).data.yunits);
+    case 'cpsd'
+      fsd.setYunits(tsao(2).data.yunits * tsao(1).data.yunits / unit('Hz'));
+    case {'cohere','mscohere'}
+      fsd.setYunits(unit());
+    otherwise
+      error(['### Unknown method:' method]);
+  end
+  
+  % set object t0
+  if eq(tsao(1).t0, tsao(2).t0)
+    fsd.setT0(tsao(1).t0);
+  end
+  
+  % make output analysis object
+  bs = ao(fsd);
+  % add standard deviation to dy field
+  bs.data.dy = dev;
+  % simplify the units
+  if strcmp(method, 'cpsd')
+    bs.simplifyYunits(...
+      plist('prefixes',false,'exceptions','Hz'),...
+      'internal');
+  end
+  
+  % set name
+  bs.name = sprintf('L%s(%s->%s)', upper(method), invars{1}, invars{2});
+  % set procinfo
+  bs.procinfo = combine(bs.procinfo,plist('r', r, 'm', m, 'l', L, 'k', K));
+  % Propagate 'plotinfo'
+  if ~isempty(tsao(1).plotinfo) || ~isempty(tsao(2).plotinfo)
+    bs.plotinfo = combine(tsao(1).plotinfo, tsao(2).plotinfo);
+  end
+  % Add history
+  bs.addHistory(mi, pl, [invars(:)], inhists);
+  
+  
+  % Set output
+  varargout{1} = bs;
+end
+% END