Mercurial > hg > ltpda
view m-toolbox/classes/@ao/lpsd.m @ 45:a59cdb8aaf31 database-connection-manager
Merge
author | Daniele Nicolodi <nicolodi@science.unitn.it> |
---|---|
date | Tue, 06 Dec 2011 19:07:22 +0100 |
parents | f0afece42f48 |
children |
line wrap: on
line source
% LPSD implements the LPSD algorithm for analysis objects. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % DESCRIPTION: LPSD implements the LPSD algorithm for analysis objects. % % CALL: bs = lpsd(a1,a2,a3,...,pl) % bs = lpsd(as,pl) % bs = as.lpsd(pl) % % INPUTS: aN - input analysis objects % as - input analysis objects array % pl - input parameter list % % OUTPUTS: bs - array of analysis objects, one for each input % % <a href="matlab:utils.helper.displayMethodInfo('ao', 'lpsd')">Parameters Description</a> % % VERSION: $Id: lpsd.m,v 1.55 2011/05/22 21:22:09 mauro Exp $ % % References: "Improved spectrum estimation from digitized time series % on a logarithmic frequency axis", Michael Troebs, Gerhard Heinzel, % Measurement 39 (2006) 120-129. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function varargout = lpsd(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 [as, ao_invars] = utils.helper.collect_objects(varargin(:), 'ao', in_names); % Decide on a deep copy or a modify bs = copy(as, nargout); % Apply defaults to plist pl = applyDefaults(getDefaultPlist, varargin{:}); inhists = []; % Loop over input AOs for jj = 1 : numel(bs) % gather the input history objects inhists = [inhists bs(jj).hist]; % check this is a time-series object if ~isa(bs(jj).data, 'tsdata') warning('!!! lpsd requires tsdata (time-series) inputs. Skipping AO %s', ao_invars{jj}); else % Check the time range. time_range = mfind(pl, 'split', 'times'); if ~isempty(time_range) switch class(time_range) case 'double' bs(jj) = split(bs(jj), plist(... 'times', time_range)); case 'timespan' bs(jj) = split(bs(jj), plist(... 'timespan', time_range)); case 'time' bs(jj) = split(bs(jj), plist(... 'start_time', time_range(1), ... 'end_time', time_range(2))); case 'cell' bs(jj) = split(bs(jj), plist(... 'start_time', time_range{1}, ... 'end_time', time_range{2})); otherwise end end % Check the length of the object if bs(jj).len <= 0 error('### The object is empty! Please revise your settings ...'); end 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(length(bs(jj).data.y), bs(jj).data.fs, Nolap, 1, Lmin, Jdes, Kdes); % compute LPSD try if find(pl, 'M-FILE ONLY') % Using pure m-file version [P, Pxx, ENBW] = ao.mlpsd_m(bs(jj).data.y, f, r, m, L, bs(jj).data.fs, Win, Order, Nolap); else [P, Pxx, dev, devxx, ENBW] = ao.mlpsd_mex(bs(jj).data.y, f, r, m, L, bs(jj).data.fs, Win, Order, Nolap*100, Lmin); end catch ME warning('!!! mex file dft failed. Using m-file version of lpsd.'); % Using pure m-file version [P, Pxx, ENBW] = ao.mlpsd_m(bs(jj).data.y, f, r, m, L, bs(jj).data.fs, Win, Order, Nolap); end % Keep the data shape of the input AO if size(bs(jj).data.y,1) == 1 P = P.'; Pxx = Pxx.'; dev = dev.'; devxx = devxx.'; f = f.'; end % create new output fsdata scale = find(pl, 'Scale'); switch lower(scale) case 'as' fsd = fsdata(f, sqrt(P), bs(jj).data.fs); fsd.setYunits(bs(jj).data.yunits); std = sqrt(dev); case 'asd' fsd = fsdata(f, sqrt(Pxx), bs(jj).data.fs); fsd.setYunits(bs(jj).data.yunits / unit('Hz^0.5')); std = sqrt(devxx); case 'ps' fsd = fsdata(f, P, bs(jj).data.fs); fsd.setYunits(bs(jj).data.yunits.^2); std = dev; case 'psd' fsd = fsdata(f, Pxx, bs(jj).data.fs); fsd.setYunits(bs(jj).data.yunits.^2/unit('Hz')); std = devxx; otherwise error(['### Unknown scaling:' scale]); end fsd.setXunits('Hz'); fsd.setEnbw(ENBW); fsd.setT0(bs(jj).data.t0); % make output analysis object bs(jj).data = fsd; % set name bs(jj).name = sprintf('L%s(%s)', upper(scale), ao_invars{jj}); % Add processing info bs(jj).procinfo = plist('r', r, 'm', m, 'l', L, 'k', K); % Add standard deviation bs(jj).data.dy = std; % Add history bs(jj).addHistory(getInfo('None'), pl, ao_invars(jj), inhists(jj)); end % End tsdata if/else end % loop over analysis objects % Set output varargout = utils.helper.setoutputs(nargout, bs); end %-------------------------------------------------------------------------- % Get Info Object %-------------------------------------------------------------------------- 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: lpsd.m,v 1.55 2011/05/22 21:22:09 mauro Exp $', sets, pl); end %-------------------------------------------------------------------------- % Get Default Plist %-------------------------------------------------------------------------- function plout = getDefaultPlist() persistent pl; if ~exist('pl', 'var') || isempty(pl) pl = buildplist(); end plout = pl; end function pl = buildplist() % General plist for Welch-based, log-scale spaced spectral estimators pl = plist.LPSD_PLIST; % Scale p = param({'Scale',['The scaling of output. Choose from:<ul>', ... '<li>PSD - Power Spectral Density</li>', ... '<li>ASD - Amplitude (linear) Spectral Density</li>', ... '<li>PS - Power Spectrum</li>', ... '<li>AS - Amplitude (linear) Spectrum</li></ul>']}, {1, {'PSD', 'ASD', 'PS', 'AS'}, paramValue.SINGLE}); pl.append(p); end % PARAMETERS: % % 'Kdes' - desired number of averages to perform [default: 100] % 'Jdes' - number of spectral frequencies to compute [default: 1000] % 'Lmin' - minimum segment length [default: 0] % 'Win' - the window to be applied to the data to remove the % discontinuities at edges of segments. [default: taken from % user prefs] % Only the design parameters of the window object are % used. Enter either: % - a specwin window object OR % - a string value containing the window name % e.g., plist('Win', 'Kaiser', 'psll', 200) % 'Olap' - segment percent overlap [default: -1, (taken from window function)] % 'Scale' - scaling of output. Choose from: % PSD - Power Spectral Density [default] % ASD - Amplitude (linear) Spectral Density % PS - Power Spectrum % AS - Amplitude (linear) Spectrum % 'Order' - order of segment detrending % -1 - no detrending % 0 - subtract mean [default] % 1 - subtract linear fit % N - subtract fit of polynomial, order N