Mercurial > hg > ltpda
view m-toolbox/classes/@ao/bin_data.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
% BIN_DATA rebins aos data, on logarithmic scale, linear scale, or arbitrarly chosen. % The rebinning is done taking the mean of the bins included in the range %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % DESCRIPTION: BIN_DATA rebins aos data, on logarithmic scale, linear scale, or arbitrarly chosen. % The rebinning is done taking the mean of the bins included in the range % % CALL: bs = bin_data(a1,a2,a3,...,pl) % bs = bin_data(as,pl) % bs = as.bin_data(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', 'bin_data')">Parameters Description</a> % % The code is inherited from D Nicolodi, UniTN % % VERSION: $Id: bin_data.m,v 1.20 2011/05/10 16:46:48 mauro Exp $ % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function varargout = bin_data(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 usepl = applyDefaults(getDefaultPlist(), varargin{:}); x_scale = find(usepl, 'x_scale', find(usepl, 'xscale')); x_vals = find(usepl, 'x_vals', find(usepl, 'xvals')); resolution = find(usepl, 'resolution'); range = find(usepl, 'range'); method = lower(find(usepl, 'method')); inherit_dy = utils.prog.yes2true(find(usepl, 'inherit-dy', find(usepl, 'inherit_dy'))); % Loop over input AOs for jj = 1:numel(bs) % check input data if isa(bs(jj).data, 'data2D') w = find(usepl, 'weights'); if isa(w, 'ao') w = w.y; end if isempty(w) w = 1./(bs(jj).dy).^2; end if isempty(x_vals) if isempty(x_scale) || isempty(resolution) error('### Please specify a scale and density for binning, OR the list of the values to bin around'); else switch lower(x_scale) case {'lin', 'linear'} % Case of linear binning % number of bins in the rebinned data set N = resolution; % maximum and minimum x if ~isempty(range) && isfinite(range(1)) xmin = range(1); else xmin = min(bs(jj).x); end if ~isempty(range) && isfinite(range(2)) xmax = range(2); else xmax = max(bs(jj).x); end dx = (xmax - xmin)/N; x_min = bs(jj).x(1) + dx*(0:(N-1))'; x_max = bs(jj).x(1) + dx*(1:N)'; case {'log', 'logarithmic'} % Case of log-based binning % maximum and minimum x if ~isempty(range) && isfinite(range(1)) xmin = range(1); else xmin = min(bs(jj).x(bs(jj).x > 0)); end if ~isempty(range) && isfinite(range(2)) xmax = range(2); else xmax = max(bs(jj).x); end alph = 10^(1/resolution); % number of bins in the rebinned data set N = ceil(log10(xmax/xmin) * resolution); % maximum and minimum x-value for each bin x_min = xmin*alph.^(0:(N-1))'; x_max = xmin*alph.^(1:N)'; otherwise error(['### Unknown scaling option ' x_scale '. Please choose between ''lin'' and ''log']); end end else % number of bins in the rebinned data set % If the x-scale is an AO, then take the x values if isa(x_vals, 'ao') if eq(x_vals.xunits, bs(jj).xunits) x_vals = x_vals.x; else error('x_vals AO and data AO have different x-units'); end elseif ~isnumeric(x_vals) error('Unsupported x_vals object'); end N = length(x_vals) - 1; x_min = x_vals(1:N); x_max = x_vals(2:N+1); end x = bs(jj).x; y = bs(jj).y; dy = bs(jj).dy; % preallocate output vectors xr = zeros(N, 1); yr = zeros(N, size(y, 2)); if strcmpi(method, 'mean') || strcmpi(method, 'wmean') dyr = zeros(N, size(y, 2)); else dyr = []; end nr = zeros(N, 1); % compute the averages for kk = 1:N in = x >= x_min(kk) & x < x_max(kk); if any(in) nr(kk) = sum(in); % number of points averaged in this bin switch method case {'mean', 'median', 'max', 'min', 'rms'} xr(kk) = feval(method, x(in)); % rebinned x bins; yr(kk) = feval(method, y(in)); % rebinned y bins; if strcmpi(method, 'mean') dyr(kk) = std(y(in), 0)/sqrt(nr(kk)); % check for zeros in the uncertainty and replace it with the individual point uncertainty if dyr(kk) == 0 if inherit_dy && ~isempty(dy) dyr(kk) = mean(dy(in)); else dyr(kk) = Inf; end end end case {'wmean'} xr(kk) = mean(x(in)); % rebinned x bins; yr(kk) = sum(y(in).*w(in))./sum(w(in)); % rebinned y bins; dyr(kk) = 1./sqrt(sum(w(in))); % rebinned dy bins; otherwise error(['### Unsupported method ' method]); end end end % remove bins where we do not have nothing to average in = nr ~= 0; nr = nr(in); xr = xr(in); yr = yr(in,:); if strcmpi(method, 'mean') || strcmpi(method, 'wmean') dyr = dyr(in,:); end % set the new object data bs(jj).setXY(xr, yr); bs(jj).setDy(dyr); % nr goes into the procinfo bs(jj).procinfo = plist('navs', nr); % set name bs(jj).name = sprintf('bin_data(%s)', ao_invars{jj}); % Add history bs(jj).addHistory(getInfo('None'), usepl, ao_invars(jj), bs(jj).hist); else warning('### Ignoring input AO number %d (%s); it is not a 2D data object.', jj, bs(jj).name) end 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: bin_data.m,v 1.20 2011/05/10 16:46:48 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() pl = plist(); % method p = param({'method',['method for binning. Choose from:<ul>', ... '<li>mean</li>', ... '<li>median</li>', ... '<li>max</li>', ... '<li>min</li>', ... '<li>rms</li>', ... '<li>weighted mean (weights can be input or are taken from data dy)</li></ul>']}, ... {1, {'MEAN', 'MEDIAN', 'MAX', 'MIN', 'RMS', 'WMEAN'}, paramValue.SINGLE}); pl.append(p); % x-scale p = param({'xscale',['scaling of binning. Choose from:<ul>', ... '<li>log - logaritmic</li>', ... '<li>lin - linear</li></ul>']}, {1, {'LOG', 'LIN'}, paramValue.SINGLE}); pl.append(p); % resolution p = param({'resolution',['When setting logaritmic x scale, it sets the number of points per decade.<br>' ... 'When setting linear x scale, it sets the number of points.']}, paramValue.DOUBLE_VALUE(10)); pl.append(p); % x_vals p = param({'xvals',['List of x values to evaluate the binning between.<br>', ... 'It may be a vector or an ao, in which case it will take the x field']}, paramValue.DOUBLE_VALUE([])); pl.append(p); % weights p = param({'weights', ['List of weights for the case of weighted mean.<br>', ... 'If empty, weights will be taken from object(s) dy field as w = 1/dy^2']}, paramValue.DOUBLE_VALUE([])); pl.append(p); % range p = param({'range', ['Range of x where to operate.<br>', ... 'If empty, the whole data set will be used']}, paramValue.DOUBLE_VALUE([])); pl.append(p); % inherit_dy p = param({'inherit_dy', ['Choose what to do in the case of mean, and bins with only one point. Choose from:<ul>', ... '<li>''yes'' - take the uncertainty from the original data, if defined</li>', ... '<li>''no'' - set it to Inf so it weighs 0 in averaged means</li></ul>' ... ]}, paramValue.YES_NO); pl.append(p); end % END