Home > src > codeSaccadesDist.m

codeSaccadesDist

PURPOSE ^

identify saccades

SYNOPSIS ^

function [ sacStruct ] = codeSaccadesDist( eyeTrack, velThreshold, stopThreshold)

DESCRIPTION ^

 identify saccades
 July 11, 2011
 Notes: This function codes the saccades
 
 syntax: [sacStruct ]  = codeSaccades( eyeTrack, velThreshold, stopThreshold )
 
 Inputs: 
       eyeTrack: vector  of complex (x+i*y) coordinates.  -1-i1  to identify
           missing data. Data should be scaled according to the image dimensions.  
           See function 'scaleEyeTrack'.
       velThreshold: min Euclidean pixel distance to travel in one sample unit time to
          be considered a saccade
       stopThreshold: max distance to travel in one sample to be considered a stop 
  
 Outputs:
       saccadeVector: vector having 0 where no fixations, then 1, 2 ,3,
           and so on for the fixations in the sequence
       startSacPos: in format [ x x x ... x; y y y ... y]
       endSacPos: in format [ x x x ... x; y y y ... y]

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 % identify saccades
0002 % July 11, 2011
0003 % Notes: This function codes the saccades
0004 %
0005 % syntax: [sacStruct ]  = codeSaccades( eyeTrack, velThreshold, stopThreshold )
0006 %
0007 % Inputs:
0008 %       eyeTrack: vector  of complex (x+i*y) coordinates.  -1-i1  to identify
0009 %           missing data. Data should be scaled according to the image dimensions.
0010 %           See function 'scaleEyeTrack'.
0011 %       velThreshold: min Euclidean pixel distance to travel in one sample unit time to
0012 %          be considered a saccade
0013 %       stopThreshold: max distance to travel in one sample to be considered a stop
0014 %
0015 % Outputs:
0016 %       saccadeVector: vector having 0 where no fixations, then 1, 2 ,3,
0017 %           and so on for the fixations in the sequence
0018 %       startSacPos: in format [ x x x ... x; y y y ... y]
0019 %       endSacPos: in format [ x x x ... x; y y y ... y]
0020 %
0021 
0022 function [  sacStruct  ] = codeSaccadesDist( eyeTrack, velThreshold, stopThreshold)
0023 
0024     if nargin < 2 || isempty( velThreshold)
0025         velThreshold = 20;
0026     end
0027     if nargin < 3 || isempty( stopThreshold )
0028         stopThreshold = 8;
0029     end
0030 
0031     numSamples =  length( eyeTrack);
0032     saccadeVec = zeros(numSamples ,1);
0033     startSacPos = zeros( 2, numSamples );
0034     endSacPos = zeros( 2, numSamples );
0035     startPos = 1; 
0036     peakVelIdx = 1; %make sure it starts, will become -1 if none
0037     k1 = 1;
0038     % find all saccades based on a velocity threshold
0039     while (peakVelIdx > 0) && (startPos < numSamples ) 
0040             [ sacIdxStart sacIdxEnd peakVelIdx] = findSaccade(  eyeTrack, velThreshold, stopThreshold, startPos );
0041             if (peakVelIdx > 0)
0042                 startSacPos(:,k1) = [ real( eyeTrack(sacIdxStart)); imag( eyeTrack(sacIdxStart))  ];
0043                 endSacPos(:,k1) = [ real( eyeTrack(sacIdxEnd)); imag( eyeTrack(sacIdxEnd))  ];                    
0044                 saccadeVec(sacIdxStart:sacIdxEnd) = k1;
0045                 startPos = sacIdxEnd+1;
0046                 k1 = k1+1;
0047             end                       
0048     end
0049     
0050     startSacPos(:,k1:end) = []; %clean up unused parts
0051     endSacPos(:,k1:end) = [];
0052     
0053     sacStruct.saccadeVec = saccadeVec;
0054     sacStruct.startSacPos = startSacPos;
0055     sacStruct.endSacPos = endSacPos;
0056       
0057     
0058 end
0059 
0060 %---------------------------------------------------
0061  %--------------------------------------------------------
0062  
0063 function [ sacIdxStart, sacIdxEnd, peakVelIdx] = findSaccade(  eyeTrack, velThreshold, stopThreshold, startPos )
0064 
0065 
0066     %--------------- initialize -----------------------
0067     windowSize = 2;
0068     minTracksToConsider = 2;
0069     numSamples = length( eyeTrack);
0070     dist = -1*ones( numSamples,1);
0071     eyeTrack =  [ real( eyeTrack(:)) imag(eyeTrack(:)) ]'; % in [ x x ... x; y y ... y ]
0072     maxPos = size( eyeTrack,2) - windowSize+1;
0073 
0074     peakVelIdx = -1;
0075     sacIdxStart = startPos;
0076     sacIdxEnd = -1;
0077     
0078     % specify search start position
0079     if nargin < 4 || isempty( startPos )   
0080         i1 = 0;
0081     else
0082         i1 =  startPos-1;
0083     end
0084 
0085     %--------------------------------------------------------
0086     %-----------find saccade based on velocity threshold ----------
0087     saccadeFound = 0;
0088     while (i1 < maxPos) 
0089         %increment, until start with not missing if necessary
0090          i1 =  i1+1;     
0091         while (i1 < maxPos) && (eyeTrack(1,i1)==-1) 
0092             i1 =  i1+1; 
0093         end
0094         % select window of windowSize samples, expand if
0095         % too much missing data or if last sample is missing
0096         i2 = 0; %for expanding window
0097         
0098         
0099         window = eyeTrack(:, i1:(i1+windowSize-1));        
0100         missIdx = find( window(1,:) == -1 );
0101         window( :, missIdx ) = [];
0102         window = reshape( window, 2,[]);
0103         
0104         while ( (size( window,2) < minTracksToConsider ) || ...
0105                     (eyeTrack(1, i1+windowSize-1+i2)==-1)  ) ...
0106                      && (i1+i2)<maxPos  % do not expand too far
0107             i2 = i2+1;
0108             window = eyeTrack(:, i1:(i1+windowSize-1+i2));
0109             missIdx = find( window(1,:) == -1 );
0110             window( :, missIdx ) = [];
0111         end
0112 
0113         % find start position, and end position of saccade based on a
0114         % threshold velocity for starting slow, middle fast, end slow
0115         window = reshape( window, 2,[]);  
0116         if size( window,2) >= minTracksToConsider %handle missing data
0117             % distance traveled per time unit
0118             dist(i1) = norm( [window(:,end) - window(:,1)], 'fro')/(windowSize+i2-1); 
0119             if (dist(i1) < stopThreshold) && ( saccadeFound < 1) %start condition
0120                 sacIdxStart = i1;
0121             end
0122             if (dist(i1) > velThreshold) && (sacIdxStart >0 ) %threshold condition
0123                 saccadeFound = i1;
0124             end
0125             if (dist(i1) < stopThreshold) && ( saccadeFound > 1) %end condition
0126                 if sacIdxEnd < 0 % set initial slowdown
0127                     sacIdxEnd = i1;                
0128                 end
0129                 if dist(i1) > dist( sacIdxEnd )  % find end point (when start speeding up again)
0130                     [ peakVel peakVelIdx   ] = max( dist(sacIdxStart:sacIdxEnd));
0131                     peakVelIdx = peakVelIdx+ sacIdxStart-1;                    
0132                     break;
0133                 else % gaze still slowing down
0134                     sacIdxEnd = i1;
0135                 end
0136             end            
0137         end            
0138     end % end while
0139 
0140     % don't count saccade if no end point
0141     if ( saccadeFound > 1) && sacIdxEnd ==-1        
0142         peakVelIdx =-1;
0143         sacIdxStart = -1;
0144     end
0145 
0146 end
0147

Generated on Wed 20-Jan-2016 11:50:43 by m2html © 2005