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
+ − % ....]