Mercurial > hg > ltpda
diff m-toolbox/classes/@ao/whiten1D.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/whiten1D.m Wed Nov 23 19:22:13 2011 +0100 @@ -0,0 +1,244 @@ +% WHITEN1D whitens the input time-series. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% DESCRIPTION: WHITEN1D whitens the input time-series. The filter is built +% by fitting to the model provided. If no model is provided, a +% fit is made to a spectral-density estimate of the +% time-series (made using psd+bin_data or lpsd). +% Note: The function assumes that the input model corresponds +% to the one-sided psd of the data to be whitened. +% +% ALGORITHM: +% 1) If no model provided, make psd+bin_data or lpsd +% of time-series and take it as a model +% for the data power spectral density +% 2) Fit a set of partial fraction z-domain filters using +% utils.math.psd2wf. The fit is automatically stopped when +% the accuracy tolerance is reached. +% 3) Convert to array of MIIR filters +% 4) Assemble into a parallel filterbank object +% 5) Filter time-series in parallel +% +% +% CALL: b = whiten1D(a, pl) +% [b1,b2,...,bn] = whiten1D(a1,a2,...,an, pl); +% +% INPUT: +% - as are time-series analysis objects or a vector of +% analysis objects +% - pl is a plist with the input parameters +% +% OUTPUT: +% - bs "whitened" time-series AOs. The whitening filters used +% are stored in the objects procinfo field under the +% parameter 'Filter'. +% +% <a href="matlab:utils.helper.displayMethodInfo('ao', 'whiten1D')">Parameters Description</a> +% +% VERSION: $Id: whiten1D.m,v 1.43 2011/04/08 08:56:12 hewitson Exp $ +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +function varargout = whiten1D(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); + inhists = [as.hist]; + + % combine plists + if isempty(pl) + model = 'psd'; + else + model = find(pl, 'model'); + if isempty(model) + model = 'psd'; + end + end + + if ischar(model) + pl = parse(pl, getDefaultPlist(model)); + else + pl = parse(pl, getDefaultPlist('Default')); + end + pl.getSetRandState(); + + scale = find(pl, 'scaleOut'); + flim = find(pl, 'flim'); + + + % Loop over input AOs + for jj = 1:numel(as) + if ~isa(as(jj).data, 'tsdata') + utils.helper.msg(msg.IMPORTANT, '%s expects ao/tsdata objects. Skipping AO %s', mfilename, ao_invars{jj}); + else + + %-------------- Whiten this AO + + % 1) Build whitening filterbank + switch class(model) + case 'char' + % Model is to be evaluated from data + in = as(jj); + pl.pset('model', model); + case 'ao' + % Model was provided as fsdata + in = model; + pl.pset('model', []); + end + wf = buildWhitener1D(in, pl); + + % 1.5) Scale the date if demanded + if (scale) + spsd = lpsd(as(jj)); + freqs = spsd.x; + if isempty(flim) + error('Please specify a flim field, to know the analysis band.'); + elseif (flim(2) < flim(1)) + error('flim should go from the smaller frequency to the bigger frequency. Please reverse them!') + else + index = find((freqs > flim(1)) & (freqs < flim(2))); + end + + v1 = spsd.y(index(1):index(end-1)); + v2 = spsd.y(index(2):index(end)); + m = (v1 + v2) /2; + p = sum(m.* diff(freqs(index(1):index(end)))); + end + + % 2) Filter data and scale it if necessary + bs(jj).filter(wf); + if (scale) + bs(jj) = bs(jj) * sqrt(p); + end + + + % 3) Output data + % name for this object + bs(jj).name = sprintf('whiten1D(%s)', ao_invars{jj}); + % Collect the filters into procinfo + bs(jj).procinfo = combine(plist('Filter', wf.filters), as(jj).procinfo); + if(scale) + bs(jj).procinfo = combine(plist('ScaleFactor', p, 'Filter', wf.filters), as(jj).procinfo); + end + % Make sure that the output yunits are empty + if ~eq(bs(jj).yunits, unit('')) + utils.helper.msg(msg.PROC1, 'Resetting output yunits to empty'); + bs(jj).setYunits(unit('')); + end + % add history + bs(jj).addHistory(getInfo('None'), pl, ao_invars(jj), inhists(jj)); + % clear errors + bs(jj).clearErrors; + + + end + end + + + + % 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 + +%-------------------------------------------------------------------------- +% Get Info Object +%-------------------------------------------------------------------------- +function ii = getInfo(varargin) + if nargin == 1 && strcmpi(varargin{1}, 'None') + sets = {}; + pl = []; + elseif nargin == 1 && ~isempty(varargin{1}) && ischar(varargin{1}) + sets{1} = varargin{1}; + pl = getDefaultPlist(sets{1}); + else + sets = SETS(); + % get plists + pl(size(sets)) = plist; + for kk = 1:numel(sets) + pl(kk) = getDefaultPlist(sets{kk}); + end + end + % Build info object + ii = minfo(mfilename, 'ao', 'ltpda', utils.const.categories.sigproc, '$Id: whiten1D.m,v 1.43 2011/04/08 08:56:12 hewitson Exp $', sets, pl); +end + + +%-------------------------------------------------------------------------- +% Defintion of Sets +%-------------------------------------------------------------------------- + +function out = SETS() + out = ao.getInfo('buildWhitener1D').sets; +end + +%-------------------------------------------------------------------------- +% Get Default Plist +%-------------------------------------------------------------------------- +function plout = getDefaultPlist(set) + persistent pl; + persistent lastset; + if ~exist('pl', 'var') || isempty(pl) || ~strcmp(lastset, set) + pl = buildplist(set); + lastset = set; + end + plout = pl; +end + +function pl = buildplist(set) + + pl = plist(); + + % Append sets of parameters according to the chosen spectral estimator + if ~utils.helper.ismember(lower(SETS), lower(set)) + error('### Unknown set [%s]', set); + else + pl = ao.getInfo('buildWhitener1D', lower(set)).plists; + end + + switch lower(set) + case 'default' + % Model + p = param({'model', ['A frequency-series AO describing the model<br>'... + 'response to build the filter from. <br>' ... + 'As an alternative, the user '... + 'can choose a model estimation technique:<br>'... + '<li>PSD - using <tt>psd</tt> + <tt>bin_data</tt></li>'... + '<li>LPSD - using <tt>lpsd</tt></li>']}, paramValue.EMPTY_DOUBLE); + pl = combine(plist(p), pl); + otherwise + end + + p = param({'scaleOut', ['Scale your output by the inband power']},paramValue.FALSE_TRUE); + pl = combine(plist(p), pl); + + p = param({'flim', ['Band to calculate the scaling power']},[1e-3 30e-3]); + pl = combine(plist(p), pl); + + +end +