Mercurial > hg > ltpda
view m-toolbox/classes/@ao/join.m @ 25:79dc7091dbbc database-connection-manager
Update tests
author | Daniele Nicolodi <nicolodi@science.unitn.it> |
---|---|
date | Mon, 05 Dec 2011 16:20:06 +0100 |
parents | f0afece42f48 |
children |
line wrap: on
line source
% JOIN multiple AOs into a single AO. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % DESCRIPTION: JOIN multiple AOs into a single AO. % If any two AOs overlap, then the values from the first appear % in the output AO. % % Note: If the input AOs are of type 'tsdata', then they will % be sorted in ascending order according the t0 of each % object. % % % CALL: bs = join(a1,a2,a3,...,pl) % bs = join(as,pl) % bs = as.join(pl) % % INPUTS: aN - input analysis objects % as - input analysis objects array % pl - input parameter list % % OUTPUTS: b - output analysis object % % <a href="matlab:utils.helper.displayMethodInfo('ao', 'join')">Parameters Description</a> % % REMARK: Input AOs should be of the same type; if not, only AOs of the % type of the first input AO will be joined together to produce % the output. % % VERSION: $Id: join.m,v 1.60 2011/09/02 11:11:51 ingo Exp $ % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % PARAMETERS: 'zerofill' - Fills with zeros the gaps between the data % points of the subsequent aos. [Default: 'no'] % 'sameT0' - Does not recalculate t0 but uses the common % one. [Default: 'no'] % Note: the t0 among different objects must be the same! % function varargout = join(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); pl = utils.helper.collect_objects(varargin(:), 'plist', in_names); % Combine plists pl = parse(pl, getDefaultPlist); %---------------------------------------------- % Get data type from the first AO dtype = class(as(1).data); % Sort the input AOs by t0, if applicable if strcmp(dtype, 'tsdata') times = as.t0.double; [~, idx] = sort(times); as = as(idx); end %---------------------------------------------- % Go through each AO and collect the data of type 'dtype' histin = []; xo = []; yo = []; dxo = []; dyo = []; enbw0 = []; fs = -1; aname = ''; adescr = ''; plotinfo = []; if as(1).data.isprop('xunits') xunitsSimple = simplify(as(1).data.xunits); xunits = as(1).data.xunits; end yunitsSimple = simplify(as(1).data.yunits); yunits = as(1).data.yunits; % Get the tolerance for considering fs equal fstol = find(pl, 'fstol'); % Compute time offset for tsdata objects to avoid rounding errors later minT0milli = getMinT0(as); % loop over AOs for jj=1:numel(as) % Only get the data type we want if isa(as(jj).data, dtype) switch lower(dtype) case 'tsdata' % here we concatonate time-series t0 = (as(jj).data.t0.utc_epoch_milli - minT0milli)/1000; % make proper time vector x = as(jj).x + t0; % only add samples past the end of existing (first loop) if isempty(xo) yo = as(jj).y; xo = x; if numel(as(jj).dx) == 0 dxo = zeros(numel(as(jj).x),1); elseif numel(as(jj).dx) == 1 dxo = ones(numel(as(jj).x),1) .* as(jj).dx; else dxo = as(jj).dx; end if numel(as(jj).dy) == 0 dyo = zeros(numel(as(jj).y),1); elseif numel(as(jj).dy) == 1 dyo = ones(numel(as(jj).y),1) .* as(jj).dy; else dyo = as(jj).dy; end else idxPost = find(x > max(xo)); idxPre = find(x < min(xo)); %%%%%%%%%% Fill the gaps with zeros %%%%%%%%%% zerofill = utils.prog.yes2true(find(pl, 'zerofill')); if zerofill % Check if there is a gap between the x-values and the pre-values. if ~isempty(idxPre) interStart = x(idxPre(end)); interEnd = xo(1); nsecsPre2no = interEnd - interStart; % The gap must be larger than 1/fs in order to % fill the gap with zeros if nsecsPre2no > 1/fs x_interPre = linspace(interStart+1/fs, interEnd-1/fs, nsecsPre2no*fs-2*1/fs).'; y_interPre = zeros(length(x_interPre), 1); else x_interPre = []; y_interPre = []; end else x_interPre = []; y_interPre = []; end % Check if there is a gap between the x-values and the post-values. if ~isempty(idxPost) interStart = xo(end); interEnd = x(idxPost(1)); nsecsPost2no = interEnd - interStart; % The gap must be larger than 1/fs in order to % fill the gap with zeros if nsecsPost2no > 1/fs x_interPost = linspace(interStart+1/fs, interEnd-1/fs, nsecsPost2no*fs-1/fs).'; y_interPost = zeros(length(x_interPost), 1); else x_interPost = []; y_interPost = []; end else x_interPost = []; y_interPost = []; end else %%%%%%%%%% Don't fill the gaps with zeros %%%%%%%%%% x_interPre = []; y_interPre = []; x_interPost = []; y_interPost = []; end xo = [x(idxPre); x_interPre; xo; x_interPost; x(idxPost)]; yo = [as(jj).data.getY(idxPre); y_interPre; yo; y_interPost; as(jj).data.getY(idxPost)]; %%% Collect errors if numel(as(jj).dx) == 0 dx = zeros(numel(as(jj).x),1); elseif numel(as(jj).dx) == 1 dx = ones(numel(as(jj).x),1) .* as(jj).dx; else dx = as(jj).dx; end if numel(as(jj).dy) == 0 dy = zeros(numel(as(jj).y),1); elseif numel(as(jj).dy) == 1 dy = ones(numel(as(jj).y),1) .* as(jj).dy; else dy = [dyo; as(jj).dy]; end x_interPre = zeros(numel(x_interPre),1); y_interPre = zeros(numel(y_interPre),1); x_interPost = zeros(numel(x_interPost),1); y_interPost = zeros(numel(y_interPost),1); dxo = [dx(idxPre); x_interPre; dxo; x_interPost; dx(idxPost)]; dyo = [dy(idxPre); y_interPre; dyo; y_interPost; dy(idxPost)]; end % check fs if (fs > 0) && (abs(as(jj).fs - fs) > fstol*fs) error('### Data has different sample rates'); end % store fs fs = as(jj).fs; % check xunits if ~eq(xunitsSimple, simplify(as(jj).xunits)) error('### The x-units of the analysis objects are not the same %s <-> %s', char(xunits), char(as(jj).xunits)); end % check yunits if ~eq(yunitsSimple, simplify(as(jj).yunits)) error('### The y-units of the analysis objects are not the same %s <-> %s', char(yunits), char(as(jj).yunits)); end % store T0 T0s(jj) = as(jj).t0; case 'fsdata' %%% Collect all fsdata samples if isempty(xo) idxBefore = 1:numel(as(jj).x); idxAfter = []; else idxBefore = find(as(jj).x < xo(1)); idxAfter = find(as(jj).x > xo(end)); end xo = [as(jj).x(idxBefore); xo; as(jj).x(idxAfter)]; yo = [as(jj).y(idxBefore); yo; as(jj).y(idxAfter)]; %%% Collect all errors % dx if numel(as(jj).dx) == 0 dx = zeros(numel(as(jj).x),1); elseif numel(as(jj).dx) == 1 dx = ones(numel(as(jj).x),1) .* as(jj).dx; else dx = as(jj).dx; end dxo = [dx(idxBefore); dxo; dx(idxAfter)]; % dy if numel(as(jj).dy) == 0 dy = zeros(numel(as(jj).y),1); elseif numel(as(jj).dy) == 1 dy = ones(numel(as(jj).y),1) .* as(jj).dy; else dy = as(jj).dy; end dyo = [dy(idxBefore); dyo; dy(idxAfter)]; % enbw if numel(as(jj).data.enbw) == 0 enbw = NaN(numel(as(jj).y),1); elseif numel(as(jj).data.enbw) == 1 enbw = ones(numel(as(jj).y),1) .* as(jj).data.enbw; else enbw = as(jj).data.enbw; end enbw0 = [enbw(idxBefore); enbw0; enbw(idxAfter)]; % check fs if (fs > 0) && (abs(as(jj).fs - fs) > fstol*fs) error('### Data has different sample rates'); end % store fs fs = as(jj).fs; % check xunits if ~eq(xunitsSimple, simplify(as(jj).xunits)) error('### The x-units of the analysis objects are not the same %s <-> %s', char(xunits), char(as(jj).xunits)); end % check yunits if ~eq(yunitsSimple, simplify(as(jj).yunits)) error('### The y-units of the analysis objects are not the same %s <-> %s', char(yunits), char(as(jj).yunits)); end case 'xydata' xo = [xo; as(jj).x]; yo = [yo; as(jj).y]; if numel(as(jj).dx) == 0 dx = zeros(numel(as(jj).x),1); elseif numel(as(jj).dx) == 1 dx = ones(numel(as(jj).x),1) .* as(jj).dx; else dx = as(jj).dx; end dxo = [dxo; dx]; if numel(as(jj).dy) == 0 dy = zeros(numel(as(jj).y),1); elseif numel(as(jj).dy) == 1 dy = ones(numel(as(jj).y),1) .* as(jj).dy; else dy = as(jj).dy; end dyo = [dyo; dy]; % check xunits if ~eq(xunitsSimple, simplify(as(jj).xunits)) error('### The x-units of the analysis objects are not the same %s <-> %s', char(xunits), char(as(jj).xunits)); end % check yunits if ~eq(yunitsSimple, simplify(as(jj).yunits)) error('### The y-units of the analysis objects are not the same %s <-> %s', char(yunits), char(as(jj).yunits)); end case 'cdata' try yo = [yo; as(jj).y]; if numel(as(jj).dy) == 0 dy = zeros(numel(as(jj).y),1); elseif numel(as(jj).dy) == 1 dy = ones(numel(as(jj).y),1) .* as(jj).dy; else dy = as(jj).dy; end dyo = [dyo; dy]; catch E disp(E.message) error('### It is not possible to join the data or error because they have different dimensions.'); end % check yunits if ~eq(yunitsSimple, simplify(as(jj).yunits)) error('### The y-units of the analysis objects are not the same %s <-> %s', char(yunits), char(as(jj).yunits)); end otherwise error('### Unknown data type'); end % Collect this input history histin = [histin as(jj).hist]; % Collect the 'plotinfo' if ~isempty(as(jj).plotinfo) plotinfo = combine(plotinfo, as(jj).plotinfo); end % Collect the descriptions adescr = strcat(adescr, as(jj).description); % Collect names, invars if ~isempty(aname) if ~strcmp(aname, as(jj).name) aname = [aname ',' as(jj).name]; end else aname = as(jj).name; end else warning('!!! Ignoring AO input with data type %s', dtype); end end %---------------------------------------------- % Now sort output vectors if ~isempty(xo) [xos, idx] = sort(xo); yos = yo(idx); dxos = dxo(idx); dyos = dyo(idx); else xos = xo; yos = yo; dxos = dxo; dyos = dyo; end if all(dxos == 0) dxos = []; elseif all(diff(dxos) == 0) dxos = dxos(1); end if all(dyos == 0) dyos = []; elseif all(diff(dyos) == 0) dyos = dyos(1); end % Keep the data shape if the input AO if size(as(1).data.y,1) == 1 xos = xos.'; yos = yos.'; end %%% Build output data object switch lower(dtype) case 'tsdata' sameT0 = utils.prog.yes2true(find(pl, 'sameT0')); % % Check that all objects share the t0 % for kk = 1:numel(T0s) % if ne(T0s(kk), T0s(1)) % sameT0 = false; % end % end % if sameT0 % data = tsdata(xos, yos, fs); % data.setT0(minT0milli/1000); % else % get t0 % toffset = xos(1); % xos = xos - toffset; data = tsdata(xos, yos, fs); data.setT0((minT0milli/1000)); % data.setToffset(toffset*1000); % end data.setDx(dxos); data.setDy(dyos); data.setXunits(xunits); data.setYunits(yunits); data.collapseX; case 'fsdata' if all(isnan(enbw0)) enbw0 = []; elseif all(diff(enbw0) == 0) enbw0 = enbw0(1); end data = fsdata(xos, yos); data.setDx(dxos); data.setDy(dyos); data.setEnbw(enbw0); data.setFs(fs); data.setXunits(xunits); data.setYunits(yunits); case 'xydata' data = xydata(xos, yos); data.setDx(dxos); data.setDy(dyos); data.setXunits(xunits); data.setYunits(yunits); case 'cdata' data = cdata(yos); data.setDy(dyos); data.setYunits(yunits); end %---------------------------------------------- % Build output AO if nargout == 0 a = as(1); a.data = data; else a = ao(data); end % Set name a.name = aname; % Set description a.description = adescr; % Set plotinfo a.plotinfo = plotinfo; % Add history a.addHistory(getInfo('None'), pl, ao_invars, histin); %---------------------------------------------- % set output varargout{1} = a; 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.helper, '$Id: join.m,v 1.60 2011/09/02 11:11:51 ingo Exp $', sets, pl); ii.setArgsmin(2); end %-------------------------------------------------------------------------- % Get Default Plist %-------------------------------------------------------------------------- function plout = getDefaultPlist() persistent pl; if exist('pl', 'var')==0 || isempty(pl) pl = buildplist(); end plout = pl; end function pl = buildplist() pl = plist(); % Zero fill p = param({'zerofill','Fills with zeros the gaps between the data points of the subsequent aos.'}, paramValue.YES_NO); p.val.setValIndex(2); pl.append(p); % Same T0 p = param({'sameT0', ['Does not recalculate t0 but uses the common one.<br>', ... 'Note: the t0 among different objects must be the same!']}, paramValue.YES_NO); p.val.setValIndex(2); pl.append(p); % fstol p = param({'fstol', ['Relative tolerance between sampling frequency of different objects.<br>', ... 'Jitter in the sampling frequency by less than this amount will be neglected.<br>', ... 'If the difference is more than the set value, an error will occur.']}, paramValue.DOUBLE_VALUE(1e-6)); pl.append(p); end %-------------------------------------------------------------------------- % Get Offset of this set of time-vectors %-------------------------------------------------------------------------- function Toff = getMinT0(as) Toff = min(double(as.t0))*1e3; end