Mercurial > hg > ltpda
diff m-toolbox/classes/@ao/linedetect.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/linedetect.m Wed Nov 23 19:22:13 2011 +0100 @@ -0,0 +1,231 @@ +% LINEDETECT find spectral lines in the ao/fsdata objects. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% DESCRIPTION: LINEDETECT find spectral lines in the ao/fsdata objects. +% +% CALL: b = linedetect(a, pl) +% +% <a href="matlab:utils.helper.displayMethodInfo('ao', 'linedetect')">Parameters Description</a> +% +% VERSION: $Id: linedetect.m,v 1.15 2011/04/08 08:56:16 hewitson Exp $ +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +function varargout = linedetect(varargin) + + % Check if this is a call for parameters + if utils.helper.isinfocall(varargin{:}) + varargout{1} = getInfo(varargin{3}); + return + end + + if nargout == 0 + error('### cat cannot be used as a modifier. Please give an output variable.'); + end + + % 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); + [pli, pl_invars] = utils.helper.collect_objects(varargin(:), 'plist', in_names); + + % Decide on a deep copy or a modify + bs = copy(as, nargout); + + Na = numel(bs); + if isempty(bs) + error('### Please input at least one AO.'); + end + + % Combine plists + if ~isempty(pli) + pl = parse(pli, getDefaultPlist()); + else + pl = getDefaultPlist(); + end + + % Get parameters from plist + N = find(pl, 'N'); + fsearch = find(pl, 'fsearch'); + thresh = find(pl, 'thresh'); + + % Loop over input AOs + for jj = 1:Na + if isa(bs(jj).data, 'fsdata') + + % Make noise-floor estimate + nf = smoother(bs(jj), pl); + + % Make ratio + r = bs(jj)./nf; + + % find lines + lines = findLines(bs(jj).data.getY, r.data.getX, r.data.getY, thresh, N, fsearch); + + f = [lines(:).f]; + y = [lines(:).a]; + + % Keep the data shpare of the input AO + if size(bs(jj).data.y, 2) == 1 + f = f.'; + y = y.'; + end + + % Make output data: copy the fsdata object so to inherit all the feautures + fs = copy(bs(jj).data, 1); + + % Make output data: set the values + fs.setX(f); + fs.setY(y); + + else + error('### I can only find lines in frequency-series AOs.'); + end + + %------- Make output AO + + % make output analysis object + bs(jj).data = fs; + + bs(jj).name = sprintf('lines(%s)', ao_invars{1}); + bs(jj).addHistory(getInfo('None'), pl, ao_invars(jj), bs(jj).hist); + 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 + +%-------------------------------------------------------------------------- +% find spectral lines +function lines = findLines(ay, f, nay, thresh, N, fsearch) + + % look for spectral lines + l = 0; + pmax = 0; + pmaxi = 0; + line = []; + idx = find( f>=fsearch(1) & f<=fsearch(2) ); + for jj = 1:length(idx) + v = nay(idx(jj)); + if v > thresh + if v > pmax + pmax = v; + pmaxi = idx(jj); + end + else + if pmax > 0 + % find index when we have pmax + fidx = pmaxi; %(find(nay(1:idx(jj))==pmax)); + l = l+1; + line(l).idx = fidx; + line(l).f = f(fidx); + line(l).a = ay(fidx); + end + pmax = 0; + end + end + + % Select largest peaks + lines = []; + if ~isempty(line) + [bl, lidx] = sort([line.a], 'descend'); + lidxs = lidx(1:min([N length(lidx)])); + lines = line(lidxs); + disp(sprintf(' + found %d lines.', length([lines.f]))); + else + disp(' + found 0 lines.'); + end +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Local Functions % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% FUNCTION: getInfo +% +% DESCRIPTION: Get Info Object +% +% HISTORY: 11-07-07 M Hewitson +% Creation. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +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: linedetect.m,v 1.15 2011/04/08 08:56:16 hewitson Exp $', sets, pl); + ii.setModifier(false); +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% FUNCTION: getDefaultPlist +% +% DESCRIPTION: Get Default Plist +% +% HISTORY: 11-07-07 M Hewitson +% Creation. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +function plout = getDefaultPlist() + persistent pl; + if exist('pl', 'var')==0 || isempty(pl) + pl = buildplist(); + end + plout = pl; +end + +function pl = buildplist() + + pl = plist(); + + % N + p = param({'N', 'The maximum number of lines to return.'}, {1, {10}, paramValue.OPTIONAL}); + pl.append(p); + + % fsearch + p = param({'fsearch', 'The frequency search interval.'}, {1, {[0 1e10]}, paramValue.OPTIONAL}); + pl.append(p); + + % thresh + p = param({'thresh', 'A threshold to test normalised amplitude against. (A sort-of SNR threshold.)'}, {1, {2}, paramValue.OPTIONAL}); + pl.append(p); + + % BW + p = param({'bw', ['The bandwidth of the running median filter used to<br>'... + 'estimate the noise-floor.']}, {1, {20}, paramValue.OPTIONAL}); + pl.append(p); + + % HC + p = param({'hc', 'The cutoff used to reject outliers (0-1).'}, {1, {0.8}, paramValue.OPTIONAL}); + pl.append(p); + + +end + +% PARAMETERS: N - max number of lines to return [default: 10] +% fsearch - freqeuncy search interval [default: all] +% thresh - a threshold to test normalised amplitude spectrum against +% [default: 2] +% bw - bandwidth over which to compute median [default: 20 samples] +% hc - percent of outliers to exclude from median estimation (0-1) +% [default: 0.8]