Mercurial > hg > ltpda
view m-toolbox/classes/@ao/split.m @ 33:5e7477b94d94 database-connection-manager
Add known repositories list to LTPDAPreferences
author | Daniele Nicolodi <nicolodi@science.unitn.it> |
---|---|
date | Mon, 05 Dec 2011 16:20:06 +0100 |
parents | f0afece42f48 |
children |
line wrap: on
line source
% SPLIT split an analysis object into the specified segments. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % DESCRIPTION: SPLIT split an analysis object into the specified segments. % % CALL: b = split(a, pl) % % INPUTS: a - input analysis object % pl - input parameter list (see below for parameters) % % OUTPUTS: b - array of analysis objects % % % EXAMPLES: 1.) Split method by frequency. Get the values from 10-100 Hz % pl = plist('frequencies', [10 100]); % ao_new = split(a1, pl); % % 2.) Split method by time. % Get the values from 0.0 to 1.0 Seconds AND from 1.0 to 2.5 seconds % pl = plist('times', [0.0 1.0 1.0 2.5]); % ao_new = split(a1, pl); % % 3.) Split method by samples. % Get the samples from 1 to 50 AND from 150 to 200. % pl = plist('samples', [1 50 150 200]); % ao_new = split(a1, pl); % % 4.1) Select an interval with strings % --> t0 = time('14:00:00') % pl = plist('start_time', '14:00:01', ... % 'end_time', '14:00:02'); % ao_new = split(a1, pl); % % --> t0 = time('14:00:00') % pl = plist('start_time', '14:00:01', ... % 'duration', '00:00:02'); % ao_new = split(a1, pl); % % Select an interval with seconds % --> t0 = time(3) % pl = plist('start_time', 5, ... % 'end_time', 7); % ao_new = split(a1, pl); % % 4.2) Select an interval with time objects % --> t0 = time('14:00:00') % pl = plist('start_time', time('14:00:01'), ... % 'end_time', time('14:00:03')); % ao_new = split(a1, pl); % % --> t0 = time(3) % pl = plist('start_time', time(5), ... % 'duration', time(2)); % ao_new = split(a1, pl); % % 4.3) Select an interval with a time span object % --> t0 = time('14:00:00') % pl = plist('timespan', timespan('14:00:00', '14:00:05')); % ao_new = split(a1, pl); % % <a href="matlab:utils.helper.displayMethodInfo('ao', 'split')">Parameters Description</a> % % VERSION: $Id: split.m,v 1.112 2011/10/05 15:43:36 ingo Exp $ % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function varargout = split(varargin) callerIsMethod = utils.helper.callerIsMethod; %%% 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); if nargout == 0 error('### split 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 = utils.helper.collect_objects(varargin(:), 'plist', in_names); % copy input plist pl = combine(pli, plist); % combine input plists (if the input plists are more than one) pl = parse(pl); % Unpack parameter list split_type = find(pl, 'split_type'); % Set 'split_type' if some other key-word is set. if pl.isparam('samples') split_type = 'samples'; elseif pl.isparam('times') || pl.isparam('frequencies') split_type = 'times'; elseif pl.isparam('chunks') || pl.isparam('N') split_type = 'chunks'; elseif pl.isparam('start_time') || pl.isparam('timespan') split_type = 'interval'; end if isempty(split_type) error('### please specify the key ''split_type'' in the parameter list'); end %%% go through analysis objects bo = []; inhists = []; for jj=1:numel(as) % gather the input history objects inhists = [inhists as(jj).hist]; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % splitting by time or frequency % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% switch lower(split_type) case {'times', 'frequencies'} times = find(pl, 'times'); frequencies = find(pl, 'frequencies'); if ~isempty(times) utils.helper.msg(msg.PROC1, 'splitting by time'); split_x_axis.type = 'times'; split_x_axis.value = times; if ~(isa(as(jj).data, 'tsdata') || isa(as(jj).data, 'xydata')) error('### I can only split time-series by times'); end else utils.helper.msg(msg.PROC1, 'splitting by frequency'); split_x_axis.type = 'frequencies'; split_x_axis.value = frequencies; if ~isa(as(jj).data, 'fsdata') error('### I can only split frequency-series by frequencies'); end end % examine time list ntimes = length(split_x_axis.value); if mod(ntimes, 2) ~= 0 error('### please specify a start and stop for each interval.') end % go over each interval now for ii=1:2:ntimes is = split_x_axis.value(ii); ie = split_x_axis.value(ii+1); ish = is; % Backup the start time for the history ieh = ie; % Backup the end time for the history if ie < 0 % indicates count from end if isa(as(jj).data, 'tsdata') ie = as(jj).data.nsecs + as(jj).toffset + ie; else ie = as(jj).x(end) + ie; end if ie < is error('### End time is before the start time.'); end elseif ie == 0 % Go to end of vector % x(end) is to small because the find command compares only to % 'less' and not to 'less or equal' ie = as(jj).x(end)+1/as(jj).fs; else ie = ie; end % copy the data-object because we change the values. d = copy(as(jj).data, nargout); % create index of the interval idx = as(jj).x >= is & as(jj).x < ie; % set output data if isempty(as(jj).data.x) % set t0 rounding at a multiplier of the sampling interval if is < as(jj).toffset % Don't change the toffset because the start time is smaller % than the toffset and this means that we collect all data % from the begin of the samples. else d.setToffset((ceil(is*d.fs)/d.fs)*1e3); end else d.setX(as(jj).x(idx)); end d.setY(as(jj).data.y(idx)); if numel(as(jj).data.dx) > 1 d.setDx(as(jj).data.dx(idx)); end if numel(as(jj).data.dy) > 1 d.setDy(as(jj).data.dy(idx)); end if isprop(as(jj).data, 'enbw') if numel(as(jj).data.enbw) > 1 d.setEnbw(as(jj).data.enbw(idx)); end end % Set nsecs for tsdata if isa(d, 'tsdata') d.collapseX; if ~isempty(d.x) d.setNsecs(d.x(end) - d.x(1) + 1/d.fs); else d.setNsecs(length(d.y)/d.fs); end end % Copy input AO b = copy(as(jj), nargout); b.data = d; if ~callerIsMethod % create new output history b.addHistory(getInfo('None'), pl.pset(split_x_axis.type, [ish ieh]), ao_invars(jj), inhists(jj)); % set name b.name = sprintf('split(%s)', ao_invars{jj}); end % Add to output array bo = [bo b]; end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % splitting by samples % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% case 'samples' utils.helper.msg(msg.PROC1, 'splitting by samples'); % examine time list samples = find(pl, 'samples'); npairs = length(samples); if mod(npairs, 2) ~= 0 error('### please specify a start and stop for each interval.') end % check data if isa(as(jj).data, 'data2D') && length(as(jj).x) ~= length(as(jj).y) error('### Something is wrong with the x/y vectors. I can''t split this data.'); end % go over each interval now for ii=1:2:npairs is = samples(ii); ie = samples(ii+1); utils.helper.msg(msg.PROC1, sprintf('Split: %03d [%d..%d]', (ii+1)/2, is, ie)); % copy the data object. d = copy(as(jj).data, nargout); if is > length(d.getY) idx = []; else idx = is:min(ie, length(d.getY)); end if isa(d, 'cdata') d.setY(d.getY(idx)); if numel(d.getDy) > 1 d.setDy(d.getDy(idx)); end else % set new samples d.setXY(d.getX(idx), d.getY(idx)); % set 'dx' and 'dy' and 'enbw' if numel(d.getDx) > 1 d.setDx(d.getDx(idx)); end if numel(d.getDy) > 1 d.setDy(d.getDy(idx)); end if isprop(d, 'enbw') if numel(d.enbw) > 1 d.setEnbw(d.enbw(idx)); end end % if this is tsdata, we can collapse it again, maybe if isa(d, 'tsdata') [fs,t0,fitted] = tsdata.fitfs(d.x); if ~fitted d.collapseX(); end end end % Copy input AO b = copy(as(jj), nargout); b.data = d; if ~callerIsMethod % create new output history b.addHistory(getInfo('None'), pl.pset('samples', [is ie]), ao_invars(jj), inhists(jj)); % set name b.name = sprintf('split(%s)[%d]', ao_invars{jj},(ii+1)/2); end % Add to output array bo = [bo b]; end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % splitting into chunks % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% case 'chunks' pl = combine(pl, getDefaultPlist('By chunks')); N = find(pl, 'N'); if isempty(N) N = pl.find('chunks'); end match = pl.find('match'); utils.helper.msg(msg.PROC1, 'splitting into %d chunks', N); y = as(jj).y; % chunk size csize = floor(length(y)/N); % generate list of indices is = 1:csize:length(y); ie = csize:csize:length(y); idx = sort([is(1:N) ie(1:N)]); if match == true idx(end) = length(y); end % one call to split with these samples b = ltpda_run_method(@split, as(jj), plist('split_type', 'samples', 'samples', idx)); % Add to output array bo = [bo b]; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % splitting into interval % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% case 'interval' %%% Skip an AO if the data is not a time-series object if ~isa(as(jj).data, 'tsdata') continue end %%% get values from the parameter list duration = find(pl, 'duration'); start_time = find(pl, 'start_time'); end_time = find(pl, 'stop_time', find(pl, 'end_time')); time_span = find(pl, 'timespan'); %%% Some checks if (~isempty(start_time) || ~isempty(end_time)) && ~isempty(time_span) error('### Please specify only a timespan and not additionally the start/end time'); end if isa(time_span, 'history') % The timespan object may have been replaced with its history in % the previous loop exection in the call to ao/addHistory time_span = rebuild(time_span); pl.pset('timespan', time_span); end %%% Convert the start_time into a time object if ~isempty(start_time) && ~isa(start_time, 'time') start_time = time(start_time); end %%% Convert the end_time into a time object if ~isempty(end_time) && ~isa(end_time, 'time') end_time = time(end_time); end %%% Convert the duration if ~isempty(end_time) && ~isempty(duration) error('### Please specify only a duration or an end time'); end if ~isempty(duration) duration = time(duration); end_time = start_time + duration; end_time = time(end_time); end %%% Set start/end time with a timespan object if ~isempty(time_span) if ~isa(time_span, 'timespan') error('### The timespan must be a timespan object') end if ~isempty(start_time) || ~isempty(end_time) error('### Please specify only a timespan OR a start/end time'); end start_time = time_span.startT; end_time = time_span.endT; end t0_time = as(jj).data.t0; %%% Compute the start/end time ts = double(start_time) - double(t0_time); te = double(end_time) - double(t0_time); idx = as(jj).x >= ts & as(jj).x < te; %%% create new output data d = copy(as(jj).data, nargout); % set output data if isempty(d.x) % set t0 rounding at a multiplier of the sampling interval if any(ts < d.toffset/1e3) % Don't change the toffset because the start time is smaller % than the toffset and this means that we collect all data from % the begin of the samples. else % d.setToffset(d.toffset + (ceil(ts*d.fs)/d.fs)*1e3); d.setToffset((ceil(ts*d.fs)/d.fs)*1e3); end else d.setX(d.getX(idx)); end d.setY(d.y(idx)); if (numel(d.getDx) > 1) d.setDx(d.getDx(idx)); end if (numel(d.getDy) > 1) d.setDy(d.getDy(idx)); end if isprop(d, 'enbw') if numel(d.enbw) > 1 d.setEnbw(d.enbw(idx)); end end % Set nsecs for tsdata if isa(d, 'tsdata') d.collapseX; if ~isempty(d.x) d.setNsecs(d.x(end) - d.x(1) + 1/d.fs); else d.setNsecs(length(d.y)/d.fs); end end % Copy input AO b = copy(as(jj), nargout); b.data = d; if ~callerIsMethod % create new output history b.addHistory(getInfo('None'), pl, ao_invars(jj), inhists(jj)); % set name b.name = sprintf('split(%s)', ao_invars{jj}); end % Add to output array bo = [bo b]; otherwise error('### Unknown split type %s', split_type); end % switch lower(split_type) end % for jj = 1:numel(as) % Set output if nargout == numel(bo) % List of outputs for ii = 1:numel(bo) varargout{ii} = bo(ii); end else % Single output varargout{1} = bo; end end %-------------------------------------------------------------------------- % Get Info Object %-------------------------------------------------------------------------- function ii = getInfo(varargin) if nargin == 1 && strcmpi(varargin{1}, 'None') sets = {}; pls = []; elseif nargin == 1 && ~isempty(varargin{1}) && ischar(varargin{1}) sets{1} = varargin{1}; pls = getDefaultPlist(sets{1}); else sets = {... 'Default', ... 'By Times', ... 'By Frequencies', ... 'By Samples', ... 'By Chunks', ... 'By Interval Start/End', ... 'By Interval Start/Duration', ... 'By Interval Timespan'}; pls = []; for kk=1:numel(sets) pls = [pls getDefaultPlist(sets{kk})]; end end % Build info object ii = minfo(mfilename, 'ao', 'ltpda', utils.const.categories.sigproc, '$Id: split.m,v 1.112 2011/10/05 15:43:36 ingo Exp $', sets, pls); ii.setModifier(false); 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(); switch lower(set) case 'default' pl = getDefaultPlist('by times'); case 'by times' % Times p = param({'times',['Split the ao into time segments.<br>' .... 'An array of start/stop times to split by. A negative stop time is ',... 'taken from the end of the vector, e.g., [10 -10] removes 10 seconds ',... 'from the beginning and end of the vector. An end time of 0 indicates ',... 'the end of the vector.']}, paramValue.EMPTY_DOUBLE); pl.append(p); case 'by frequencies' % Frequencies p = param({'frequencies','An array of start/stop frequencies to split by.'}, paramValue.EMPTY_DOUBLE); pl.append(p); case 'by samples' % samples p = param({'samples','An array of start/stop samples to split by.'}, paramValue.EMPTY_DOUBLE); pl.append(p); case 'by chunks' % N p = param({'N','Split into N contiguous pieces.'}, paramValue.EMPTY_DOUBLE); pl.append(p); % match p = param({'match','Define if the last chunk should keep any remaining data samples.'}, paramValue.TRUE_FALSE); pl.append(p); case 'by interval start/end' % start_time p = param({'start_time','Start time can be either a string or a time object.'}, {1, {time(0)}, paramValue.OPTIONAL}); pl.append(p); % end_time p = param({'end_time','End time can be either a string or a time object.'}, {1, {time(0)}, paramValue.OPTIONAL}); pl.append(p); case 'by interval start/duration' % start_time p = param({'start_time','Start time can be either a string or a time object.'}, {1, {time(0)}, paramValue.OPTIONAL}); pl.append(p); % duration p = param({'duration','Duration can be either a string or a time object.'}, {1, {time(0)}, paramValue.OPTIONAL}); pl.append(p); case 'by interval timespan' % timespan p = param({'timespan','The start/end time are specified in the time span object.'}, {1, {timespan(0,0)}, paramValue.OPTIONAL}); pl.append(p); otherwise error('### Unknown parameter set [%s].', set); end end % PARAMETERS: <key> <value> <description> % 'split_type' 'times' split the ao into time segments % 'frequencies' split the ao into frequencies segments % 'samples' split the ao into sample segments % 'chunks' split the ao into chunks % 'interval' select a duration of a tsdata % % Necessary for the individual split types: % <split type> <key> <description> % 'times' 'times' an array of start/stop times to % split by. A negative stop time is % taken from the end of the vector, % e.g., [10 -10] removes 10 seconds % from the beginning and end of the % vector. An end time of 0 % indicates the end of the vector. % ------------------------------------------------------------- % 'frequencies' 'frequencies' an array of start/stop % frequencies to split by % ------------------------------------------------------------- % 'samples' 'samples' an array of start/stop samples to % split by % ------------------------------------------------------------- % 'chunks' 'N' split into N contiguous pieces % 'match' define if the last chunk should % keep the remaining data samples % which couldn't split in all chunks % default [true] % ------------------------------------------------------------- % 'interval' 'start_time', 'end_time' % start/stop time can be either a string or a % time object % 'interval' 'start_time', 'duration' % start time and the duration can be either a % string or a time object % 'interval' 'timespan' % the start/end time are specified in the time % span object. % ------------------------------------------------------------- % The UTC time format is: 'yyyy-mm-dd HH:MM:SS' % % If more than one splitting method is specified, the priority % goes like the list above. % % The time vector in the output AO retains the original % time values (i.e. it doesn't start from zero). % % The splitting is done as s<=t<e. % % Arrays of start/stop values should be like: [s1 e1 s2 e2 % ....]