function [ seg, seg_ind, percent_covered ] = MG_Segment_Vel_One_Player(t, x, params) % MG_SEGMENT_VEL_ONE_PLAYER - return list of segments of one player % [ seg, seg_ind, percent_covered ] = MG_Segment_Vel_One_Player(t, x, params) - % input: % t - time (put [] to use default
) % x - position % params (optional), with fields: % .min_seg_time (default 0.2 sec)- min length (in sec) of segment % 2012-11-19: % NEED TO CHECK HOW ALL, E.G IDYO 'Y' MATRIX LOOKS WITH THIS % SET TO 0.1 => 5HZ (1 cycle = 2 strokes). % .max_seg_time (default 8 sec) - same, max % .min_seg_length (default 30 ticks ~= 3cm) % .remove_threshold - compute without threshold (all segments) % output: % seg - cell array of velocity segments [in ticks-per-sec] % seg_ind - indecies of segments % percent_covered - percent from signal covered by segments % % 2012-10-31: % allow working without as input, just used to compute
, % get it instead from MG_Default_Const % % 2016-08-30: % params.butter_filter (default = 0) - add option to make Pos => Vel using Butter instead of Bfilt (for Jason project) const = MG_Default_Const; % Default Values for Optional Inputs % if ~exist('params','var'), params = []; end if ~isfield(params,'min_seg_time'), params.min_seg_time = const.min_seg_time; end if ~isfield(params,'max_seg_time'), params.max_seg_time = const.max_seg_time; end if ~isfield(params,'min_seg_length'), % minimal displacement params.min_seg_length = const.min_seg_length; end if ~isfield(params, 'butter_filter'), params.butter_filter = 0; end % get abs velociy if params.butter_filter, v0 = vel_acc_with_butter(x); v = abs(v0); % v = v / 50; % bring to same units as coming from bfilt, without './ dt' else v = abs(vel_acc_with_bfilt(x)); end % convert from speed-per-sample to speed-per-sec if ~isempty(t), dt = mean(diff(t)); else cnst = MG_Default_Const; dt = 1 / cnst.Samples_Per_Sec; end v = v / dt; % all non-zero (segments) points, binary signal % 30-Aug-2016 - parse by 'almost zero' to work with butter-filter. need to see if it changes other things z = v > 0; if params.butter_filter, % 04-09-2016: deal with butter_filter not reaching zero in segment% boundaries. % soloution: add to exact zero points (as below) pairs of points that crosses zero, treat them as 'two zero' points' (longer stop), % and create segments as before % 07-09-2016: fix false-alarms coming from tiny jitter at start z ( abs(v0) < 0.001 ) = 0; v0 ( abs(v0) < 0.001 ) = 0; ix = find( abs( sign(v0) - [0; sign(v0(1:end-1))] ) == 2 ); % get +2 & -2, both directons, of zero-crossing z( ix - 1 ) = 0; % point before cross z( ix ) = 0; % point after cross end % 11-Aug-09: % (+) for both diff, we add dummy-element to have correct placement % (+) we want the boundary to include the first 0-vel on both sides, so we % take one sample before the change for start-of-index, and the change % sample for end-of-segment % start of segments a = find( diff([z(1); z]) > 0 ) - 1; % end of segments b = find( diff([z(1); z]) < 0); % if not start or end of segment found, reutrn nothing if isempty(a) || isempty(b), seg = []; seg_ind = []; percent_covered = 0; return end % ignore partial first segment if b(1) < a(1), b = b(2:end); end % ignore partial last segment if a(end) >= b(end), a = a(1:end-1); end if length(a) == (length(b) - 1) && a(1) == b(1), % 07.09.16 - boundary case b = b(2:end); end % so we expect them to be the same length, giving start\end of non-zero segments if length(a) ~= length(b), error( 'strange, differnt length of start/end points') end len = b - a + 1; too_short = find( len < round( params.min_seg_time / dt ) ); % we convert the time request for segment length to number-of-samples too_long = find( len > round( params.max_seg_time / dt ) ); ok = setdiff( 1 : length(len), union(too_short,too_long) ); if isempty(ok), seg = []; seg_ind = []; percent_covered = 0; return end seg_ind = [a(ok), b(ok)]; % 09_07_29 = remove small segments (in position) for k = 1 : size(seg_ind,1), if abs( x(seg_ind(k,1)) - x(seg_ind(k,2)) ) < params.min_seg_length, mark(k) = 0; else mark(k) = 1; %#ok<*AGROW> end end % 09_11_03 = remove segments with NaN from MG_Clean_Sessions for k = 1 : size(seg_ind,1), if ~isempty( find( isnan( x( seg_ind(k,1):seg_ind(k,2) ) ), 1 ) ), mark(k) = 0; else mark(k) = 1; end end seg_ind = seg_ind( find(mark), : ); %#ok if isempty(seg_ind), seg = []; percent_covered = 0; return end total_seg_len = 0; for k = 1 : size(seg_ind,1), seg{k} = v(seg_ind(k,1):seg_ind(k,2)); total_seg_len = total_seg_len + length( seg{k} ); end percent_covered = round( 100*(total_seg_len / length(v)) );