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 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 'duration' 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 'interval' 'start_time', 'stop_time' - start/stop time can be either a string or a time object (if a string, 'format_str' must be specified or specify the strings in UTC time format) 'interval' 'start_time', 'duration' - start time and the duration can be either a string or a time object (if a string, 'format_str' must be specified or specify the strings in UTC time format) '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 ....] EXAMPLES: 1.) Split method by frequency. Get the values from 10-100 Hz pl = plist('split_type', 'frequencies', ... '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('split_type', 'times', ... 'times', [0.0 1.0 1.0 2.5]); ao_new = split(a1, pl); 3.) Split method by samples. Get the samples from 0 to 50 AND from 150 to 200. pl = plist('split_type', 'samples', ... 'samples', [0 50 150 200]); ao_new = split(a1, pl); 4.1) Select an interval with strings pl = plist('split_type', 'interval', ... 'start_time', '14:00:01', ... 'end_time', '14:00:02'); ao_new = split(a1, pl); pl = plist('split_type', 'interval', ... 'start_time', '14:00:01', ... 'duration', '00:00:02'); ao_new = split(a1, pl); Select an interval with milliseconds pl = plist('split_type', 'interval', ... 'start_time', 5000, ... 'end_time', 7000); ao_new = split(a1, pl); 4.2) Select an interval with time objects pl = plist('split_type', 'interval', ... 'start_time', time('14:00:01'), ... 'end_time', time('14:00:03')); ao_new = split(a1, pl); pl = plist('split_type', 'interval', ... 'start_time', time(5000), ... 'duration', time(2000)); ao_new = split(a1, pl); 4.3) Select an interval with a time span object pl = plist('split_type', 'interval', ... 'timespan', timespan('14:00:00', '14:00:05')); ao_new = split(a1, pl); M-FILE INFO: Get information about this methods by calling >> ao.getInfo('split') Get information about a specified set-plist by calling: >> ao.getInfo('split', 'Default') VERSION: $Id: split.m,v 1.56 2008/09/05 11:05:29 ingo Exp $ HISTORY: 02-03-07 M Hewitson Creation. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0001 % SPLIT split an analysis object into the specified segments. 0002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0003 % 0004 % DESCRIPTION: SPLIT split an analysis object into the specified segments. 0005 % 0006 % CALL: b = split(a, pl) 0007 % 0008 % INPUTS: a - input analysis object 0009 % pl - input parameter list (see below for parameters) 0010 % 0011 % OUTPUTS: b - array of analysis objects 0012 % 0013 % PARAMETERS: <key> <value> <description> 0014 % 'split_type' 'times' split the ao into time segments 0015 % 'frequencies' split the ao into frequencies segments 0016 % 'samples' split the ao into sample segments 0017 % 'chunks' split the ao into chunks 0018 % 'duration' select a duration of a tsdata 0019 % 0020 % Necessary for the individual split types: 0021 % <split type> <key> <description> 0022 % 'times' 'times' an array of start/stop times to 0023 % split by. A negative stop time is taken from the end 0024 % of the vector, e.g., [10 -10] removes 10 seconds from 0025 % the beginning and end of the 0026 % vector. An end time of 0 0027 % indicates the end of the vector. 0028 % 'frequencies' 'frequencies' an array of start/stop frequencies to split by 0029 % 'samples' 'samples' an array of start/stop samples to split by 0030 % 'chunks' 'N' split into N contiguous pieces 0031 % 'interval' 'start_time', 'stop_time' 0032 % - start/stop time can be either a string or a time 0033 % object (if a string, 'format_str' must be 0034 % specified or specify the strings in UTC time format) 0035 % 'interval' 'start_time', 'duration' 0036 % - start time and the duration can be either a string 0037 % or a time object (if a string, 'format_str' must be 0038 % specified or specify the strings in UTC time format) 0039 % 'interval' 'timespan' 0040 % - the start/end time are specified in the time span 0041 % object. 0042 % 0043 % The UTC time format is: 'yyyy-mm-dd HH:MM:SS' 0044 % 0045 % If more than one splitting method is specified, the priority 0046 % goes like the list above. 0047 % 0048 % The time vector in the output AO retains the original 0049 % time values (i.e. it doesn't start from zero). 0050 % 0051 % The splitting is done as s<=t<e. 0052 % 0053 % Arrays of start/stop values should be like: [s1 e1 s2 e2 ....] 0054 % 0055 % EXAMPLES: 1.) Split method by frequency. Get the values from 10-100 Hz 0056 % pl = plist('split_type', 'frequencies', ... 0057 % 'frequencies', [10 100]); 0058 % ao_new = split(a1, pl); 0059 % 0060 % 2.) Split method by time. 0061 % Get the values from 0.0 to 1.0 Seconds AND from 1.0 to 2.5 seconds 0062 % pl = plist('split_type', 'times', ... 0063 % 'times', [0.0 1.0 1.0 2.5]); 0064 % ao_new = split(a1, pl); 0065 % 0066 % 3.) Split method by samples. 0067 % Get the samples from 0 to 50 AND from 150 to 200. 0068 % pl = plist('split_type', 'samples', ... 0069 % 'samples', [0 50 150 200]); 0070 % ao_new = split(a1, pl); 0071 % 0072 % 4.1) Select an interval with strings 0073 % pl = plist('split_type', 'interval', ... 0074 % 'start_time', '14:00:01', ... 0075 % 'end_time', '14:00:02'); 0076 % ao_new = split(a1, pl); 0077 % 0078 % pl = plist('split_type', 'interval', ... 0079 % 'start_time', '14:00:01', ... 0080 % 'duration', '00:00:02'); 0081 % ao_new = split(a1, pl); 0082 % 0083 % Select an interval with milliseconds 0084 % pl = plist('split_type', 'interval', ... 0085 % 'start_time', 5000, ... 0086 % 'end_time', 7000); 0087 % ao_new = split(a1, pl); 0088 % 0089 % 4.2) Select an interval with time objects 0090 % pl = plist('split_type', 'interval', ... 0091 % 'start_time', time('14:00:01'), ... 0092 % 'end_time', time('14:00:03')); 0093 % ao_new = split(a1, pl); 0094 % 0095 % pl = plist('split_type', 'interval', ... 0096 % 'start_time', time(5000), ... 0097 % 'duration', time(2000)); 0098 % ao_new = split(a1, pl); 0099 % 0100 % 4.3) Select an interval with a time span object 0101 % pl = plist('split_type', 'interval', ... 0102 % 'timespan', timespan('14:00:00', '14:00:05')); 0103 % ao_new = split(a1, pl); 0104 % 0105 % M-FILE INFO: Get information about this methods by calling 0106 % >> ao.getInfo('split') 0107 % 0108 % Get information about a specified set-plist by calling: 0109 % >> ao.getInfo('split', 'Default') 0110 % 0111 % VERSION: $Id: split.m,v 1.56 2008/09/05 11:05:29 ingo Exp $ 0112 % 0113 % HISTORY: 02-03-07 M Hewitson 0114 % Creation. 0115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0116 0117 function varargout = split(varargin) 0118 0119 %%% Check if this is a call for parameters 0120 if utils.helper.isinfocall(varargin{:}) 0121 varargout{1} = getInfo(varargin{3}); 0122 return 0123 end 0124 0125 import utils.const.* 0126 utils.helper.msg(msg.MNAME, 'running %s/%s', mfilename('class'), mfilename); 0127 0128 if nargout == 0 0129 error('### split cannot be used as a modifier. Please give an output variable.'); 0130 end 0131 0132 % Collect input variable names 0133 in_names = cell(size(varargin)); 0134 for ii = 1:nargin,in_names{ii} = inputname(ii);end 0135 0136 % Collect all AOs 0137 [as, ao_invars] = utils.helper.collect_objects(varargin(:), 'ao', in_names); 0138 pli = utils.helper.collect_objects(varargin(:), 'plist', in_names); 0139 0140 % copy input plist 0141 pl = copy(pli, 1); 0142 0143 %%% go through analysis objects 0144 bo = []; 0145 for j=1:numel(as) 0146 0147 % Unpack parameter list 0148 split_type = find(pl, 'split_type'); 0149 0150 % check old version without the key 'split_type' 0151 if ~isempty(find(pl, 'samples')) 0152 split_type = 'samples'; 0153 elseif ~isempty(find(pl, 'times')) || ... 0154 ~isempty(find(pl, 'frequencies')) 0155 split_type = 'times'; % times is the same to frequencies 0156 end 0157 0158 if isempty(split_type) 0159 error('### please specify the key ''split_type'' in the parameter list'); 0160 end 0161 0162 % look at input data 0163 x = as(j).data.getX; 0164 y = as(j).data.getY; 0165 0166 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0167 % splitting by time or frequency % 0168 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0169 if strcmpi(split_type, 'times') || strcmpi(split_type, 'frequencies') 0170 0171 times = find(pl, 'times'); 0172 frequencies = find(pl, 'frequencies'); 0173 0174 if ~isempty(times) 0175 utils.helper.msg(msg.PROC1, 'splitting by time'); 0176 split_x_axis.type = 'times'; 0177 split_x_axis.value = times; 0178 if ~isa(as(j).data, 'tsdata') 0179 error('### I can only split time-series by times'); 0180 end 0181 else 0182 utils.helper.msg(msg.PROC1, 'splitting by frequency'); 0183 split_x_axis.type = 'frequencies'; 0184 split_x_axis.value = frequencies; 0185 if ~isa(as(j).data, 'fsdata') 0186 error('### I can only split frequency-series by frequencies'); 0187 end 0188 end 0189 0190 % examine time list 0191 ntimes = length(split_x_axis.value); 0192 if mod(ntimes, 2) ~= 0 0193 error('### please specify a start and stop for each interval.') 0194 end 0195 % go over each interval now 0196 for i=1:2:ntimes 0197 is = split_x_axis.value(i); 0198 ie = split_x_axis.value(i+1); 0199 if ie < 0 % indicates count from end 0200 ie = as(j).data.nsecs + ie; 0201 if ie < is 0202 error('### End time is before the start time.'); 0203 end 0204 elseif ie == 0 % Go to end of vector 0205 ie = length(x); 0206 end 0207 idx = find(x>=is & x <ie); 0208 0209 % copy the data-object because we change the values. 0210 d = copy(as(j).data, 1); 0211 0212 % create new output data 0213 d.setX(x(idx)); 0214 d.setY(y(idx)); 0215 0216 % Set nsecs for tsdata 0217 if isa(d, 'tsdata') 0218 d.collapseX; 0219 if ~isempty(d.x) 0220 d.setNsecs(d.x(end) - d.x(1) + 1/d.fs); 0221 else 0222 d.setNsecs(length(d.y)/d.fs); 0223 end 0224 end 0225 0226 % Make AO 0227 b = ao(d); 0228 % create new output history 0229 b.addHistory(getInfo, plist(split_x_axis.type, [is ie]), ao_invars(j), as(j).hist); 0230 % set name 0231 b.setName(sprintf('split(%s)', ao_invars{j}), 'internal'); 0232 % Add to output array 0233 bo = [bo b]; 0234 end 0235 0236 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0237 % splitting by samples % 0238 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0239 elseif strcmpi(split_type, 'samples') 0240 utils.helper.msg(msg.PROC1, 'splitting by samples'); 0241 samples = find(pl, 'samples'); 0242 % examine time list 0243 npairs = length(samples); 0244 if mod(npairs, 2) ~= 0 0245 error('### please specify a start and stop for each interval.') 0246 end 0247 % check data 0248 if length(x) ~= length(y) && ~isempty(x) 0249 error('### Something is wrong with the x/y vectors. I can''t split this data.'); 0250 end 0251 % go over each interval now 0252 utils.helper.msg(msg.PROC1, sprintf('Split: \f')); 0253 c = 1; 0254 dtmp = copy(as(j).data,1); 0255 dtmp.setXY([],[]); 0256 for i=1:2:npairs 0257 utils.helper.msg(msg.PROC1, sprintf('\b%03d ', round(c))); 0258 if mod(c,11) == 0 && c < npairs 0259 utils.helper.msg(msg.PROC1, sprintf('Chunk: \f')); 0260 end 0261 is = samples(i); 0262 ie = samples(i+1); 0263 % create new output data 0264 if ~isempty(x) 0265 x1 = x(is:ie); 0266 else 0267 x1 = []; 0268 end 0269 y1 = y(is:ie); 0270 % subtract offset of x for tsdata 0271 % - we record this info by chaging t0 0272 d = copy(as(j).data, 1); 0273 if isa(d, 'tsdata') 0274 d.setX(x1-x1(1)); 0275 else 0276 d.setX(x1); 0277 end 0278 d.setY(y1); 0279 % set t0,nsecs if this is tsdata 0280 if isa(d, 'tsdata') 0281 t0 = dtmp.t0 + x1(1); 0282 d.setT0(t0); 0283 d.setNsecs(length(y1) ./ dtmp.fs); 0284 end 0285 % Make AO 0286 b = ao(d); 0287 % create new output history 0288 b.addHistory(getInfo, plist('samples', [is ie]), ao_invars(j), as(j).hist); 0289 % set name 0290 b.setName(sprintf('split(%s)[%d]', ao_invars{j},c), 'internal'); 0291 % Add to output array 0292 bo = [bo b]; 0293 c = c + 1; 0294 end 0295 0296 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0297 % splitting into chunks % 0298 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0299 elseif strcmpi(split_type, 'chunks') 0300 N = find(pl, 'N'); 0301 utils.helper.msg(msg.PROC1, 'splitting into %d chunks', N); 0302 % chunk size 0303 csize = floor(length(y)/N); 0304 % generate list of indices 0305 idx = []; 0306 for kk=1:N 0307 is = 1+(kk-1)*csize; 0308 ie = csize*kk; 0309 idx = [idx is ie]; 0310 end 0311 % one call to split with these samples 0312 b = split(as, plist('split_type', 'samples', 'samples', idx)); 0313 bo = [bo b]; 0314 0315 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0316 % splitting into interval % 0317 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0318 elseif strcmpi(split_type, 'interval') 0319 0320 % txt = '###########################################'; 0321 % error('%s\n### Please, check this part before using it due to the fact that the objects are handles.\n%s', txt, txt) 0322 0323 %%% get values from the parameter list 0324 duration = find(pl, 'duration'); 0325 start_time = find(pl, 'start_time'); 0326 end_time = find(pl, 'end_time'); 0327 format_str = find(pl, 'format_str'); 0328 timespan = find(pl, 'timespan'); 0329 0330 %%% Some checks 0331 if (~isempty(start_time) || ~isempty(end_time)) && ~isempty(timespan) 0332 error('### Please specify only a timespan and not additionally the start/end time'); 0333 end 0334 0335 %%% Convert the start_time into a time object 0336 if ~isempty(start_time) && ~isa(start_time, 'time') 0337 start_time = time(start_time); 0338 end 0339 0340 %%% Convert the end_time into a time object 0341 if ~isempty(end_time) && ~isa(end_time, 'time') 0342 end_time = time(end_time); 0343 end 0344 0345 %%% Convert the duration 0346 if ~isempty(end_time) && ~isempty(duration) 0347 error('### Please specify only a duration or an end time'); 0348 end 0349 if ~isempty(duration) && ~isa(duration, 'time') 0350 duration = time(duration); 0351 end_time = start_time + duration; 0352 end_time = time(end_time); 0353 end 0354 0355 %%% Set start/end time with a timespan object 0356 if ~isempty(timespan) 0357 if ~isa(timespan, 'timespan') 0358 error('### The timespan must be a timespan object') 0359 end 0360 if ~isempty(start_time) || ~isempty(end_time) 0361 error('### Please specify only a timespan OR a start/end time'); 0362 end 0363 0364 start_time = timespan.startT; 0365 end_time = timespan.endT; 0366 end 0367 0368 %%% Set the end_time to the same timezone as the start_time 0369 end_time.setTimezone(start_time.timezone); 0370 0371 t0_time = as(j).data.t0; 0372 t1 = as(j).data.getX(1); 0373 0374 %%% Comput the start/end time 0375 ts = (start_time.utc_epoch_milli-t0_time.utc_epoch_milli+t1)/1000; 0376 te = (end_time.utc_epoch_milli-t0_time.utc_epoch_milli+t1)/1000; 0377 0378 idx = find(x >= ts & x < te); 0379 %%% create new output data 0380 d = copy(as(j).data,1); 0381 d.setXY(x(idx), y(idx)); 0382 % Set nsecs for tsdata 0383 if isa(d, 'tsdata') 0384 if ~isempty(d.x) 0385 d.setNsecs(d.x(end) - d.x(1) + 1/d.fs); 0386 else 0387 d.setNsecs(0); 0388 end 0389 end 0390 % Make AO 0391 b = ao(d); 0392 % create new output history 0393 b.addHistory(getInfo, pl, ao_invars(j), as(j).hist); 0394 % set name 0395 b.name = sprintf('split(%s)', ao_invars{j}); 0396 % Add to output array 0397 bo = [bo b]; 0398 0399 end 0400 end % for j = 1:numel(as) 0401 0402 % Set output 0403 varargout{1} = bo; 0404 end 0405 0406 %-------------------------------------------------------------------------- 0407 % Get Info Object 0408 %-------------------------------------------------------------------------- 0409 0410 function ii = getInfo(varargin) 0411 if nargin == 1 && strcmpi(varargin{1}, 'None') 0412 sets = {}; 0413 pls = []; 0414 elseif nargin == 1 && ~isempty(varargin{1}) && ischar(varargin{1}) 0415 sets{1} = varargin{1}; 0416 pls = getDefaultPlist(sets{1}); 0417 else 0418 sets = {... 0419 'Default', ... 0420 'By times', ... 0421 'By frequencies', ... 0422 'By samples', ... 0423 'By chunks', ... 0424 'By interval start/end', ... 0425 'By interval start/duration', ... 0426 'By interval timespan'}; 0427 pls = []; 0428 for kk=1:numel(sets) 0429 pls = [pls getDefaultPlist(sets{kk})]; 0430 end 0431 end 0432 % Build info object 0433 ii = minfo(mfilename, 'ao', '', utils.const.categories.sigproc, '$Id: split.m,v 1.56 2008/09/05 11:05:29 ingo Exp $', sets, pls); 0434 end 0435 0436 %-------------------------------------------------------------------------- 0437 % Get Default Plist 0438 %-------------------------------------------------------------------------- 0439 function plo = getDefaultPlist(set) 0440 switch set 0441 case 'Default' 0442 plo = plist('split_type', 'times', 'times', []); 0443 case 'By times' 0444 plo = plist('split_type', 'times', 'times', []); 0445 case 'By frequencies' 0446 plo = plist('split_type', 'frequencies', 'frequencies', []); 0447 case 'By samples' 0448 plo = plist('split_type', 'samples', 'samples', []); 0449 case 'By chunks' 0450 plo = plist('split_type', 'chunks', 'N', []); 0451 case 'By interval start/end' 0452 plo = plist('split_type', 'interval', 'start_time', time(0), 'end_time', time(0)); 0453 case 'By interval start/duration' 0454 plo = plist('split_type', 'interval', 'start_time', time(0), 'duration', time(0)); 0455 case 'By interval timespan' 0456 plo = plist('split_type', 'interval', 'timespan', timespan(0,0)); 0457 otherwise 0458 error('### Unknown parameter set [%s].', set); 0459 end 0460 end 0461 0462