Home > matlabmk > spatial_neighbors.m

spatial_neighbors

PURPOSE ^

spatial_neighbors() - Given a set of electrode coordinates, this function

SYNOPSIS ^

function chan_hood=spatial_neighbors(chanlocs,max_dist,head_radius)

DESCRIPTION ^

 spatial_neighbors() - Given a set of electrode coordinates, this function 
                       returns a binary 2D matrix that indicates which 
                       electrodes are close enough to be considered 
                       neighbors. For use with cluster-based permutation 
                       tests.

 Usage:
  >>chan_hood=spatial_neighbors(chanlocs,max_dist);

 Required Inputs:
   chanlocs - An EEGLAB chanlocs structure (e.g., EEG.chanlocs from an EEG
              variable)
   max_dist - All electrodes within max_dist of another electrode are
              considered spatial neighbors.  Max_dist is in whatever units
              your EEGLAB chanlocs coordinates are in.  If your chanlocs 
              coordingates are on an idealized sphere with unit radius 
              then you can convert max_dist into centimeters by measuring 
              the circumference of a participant's head in centimeters and
              using the following formulas:
                 radius=circumference/(2*pi);
                 radius*max_dist=max_dist in units of cm

 Optional Inputs:
   head_radius - The radius of the head in whatever units the Cartesian
                 coordinates in chanlocs are in. This is used to
                 convert scalar values of chan_hood into centimeters.
                 {default: estimated from chanlocs by assuming center of
                 head is at 0,0,0}

 Outputs:
   chan_hood - A symmetric binary matrix indicating which channels are
               neighbors. If chan_hood(a,b)=1, then Channel A and Channel
               B are nieghbors.

 Notes:
 -This function outputs an estimate of max_dist (in cm) on the command line
 by assuming a circumference of 56 cm and EEGLAB chanloc coordinates based 
 on a spherical head with unit radius.  It also summarizes the number of 
 neighbors per channel using basic measures of central tendency and 
 dispersion.
 -You will have more statistical power to detect effects at electrodes
 that have more neighbors.  Thus you may have significantly less power to
 detect effects on the edge of the montage.  Thanks to Manish Saggar for
 bringing this to my attention.

 Author:
 David Groppe
 Kutaslab, 5/2011

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 % spatial_neighbors() - Given a set of electrode coordinates, this function
0002 %                       returns a binary 2D matrix that indicates which
0003 %                       electrodes are close enough to be considered
0004 %                       neighbors. For use with cluster-based permutation
0005 %                       tests.
0006 %
0007 % Usage:
0008 %  >>chan_hood=spatial_neighbors(chanlocs,max_dist);
0009 %
0010 % Required Inputs:
0011 %   chanlocs - An EEGLAB chanlocs structure (e.g., EEG.chanlocs from an EEG
0012 %              variable)
0013 %   max_dist - All electrodes within max_dist of another electrode are
0014 %              considered spatial neighbors.  Max_dist is in whatever units
0015 %              your EEGLAB chanlocs coordinates are in.  If your chanlocs
0016 %              coordingates are on an idealized sphere with unit radius
0017 %              then you can convert max_dist into centimeters by measuring
0018 %              the circumference of a participant's head in centimeters and
0019 %              using the following formulas:
0020 %                 radius=circumference/(2*pi);
0021 %                 radius*max_dist=max_dist in units of cm
0022 %
0023 % Optional Inputs:
0024 %   head_radius - The radius of the head in whatever units the Cartesian
0025 %                 coordinates in chanlocs are in. This is used to
0026 %                 convert scalar values of chan_hood into centimeters.
0027 %                 {default: estimated from chanlocs by assuming center of
0028 %                 head is at 0,0,0}
0029 %
0030 % Outputs:
0031 %   chan_hood - A symmetric binary matrix indicating which channels are
0032 %               neighbors. If chan_hood(a,b)=1, then Channel A and Channel
0033 %               B are nieghbors.
0034 %
0035 % Notes:
0036 % -This function outputs an estimate of max_dist (in cm) on the command line
0037 % by assuming a circumference of 56 cm and EEGLAB chanloc coordinates based
0038 % on a spherical head with unit radius.  It also summarizes the number of
0039 % neighbors per channel using basic measures of central tendency and
0040 % dispersion.
0041 % -You will have more statistical power to detect effects at electrodes
0042 % that have more neighbors.  Thus you may have significantly less power to
0043 % detect effects on the edge of the montage.  Thanks to Manish Saggar for
0044 % bringing this to my attention.
0045 %
0046 % Author:
0047 % David Groppe
0048 % Kutaslab, 5/2011
0049 
0050 %%%%% Future Work %%%%%%
0051 % -Perhaps allow max_dist to be specified in centimeters
0052 
0053 function chan_hood=spatial_neighbors(chanlocs,max_dist,head_radius)
0054 
0055 n_chan=length(chanlocs);
0056 
0057 if nargin<3,
0058     head_radius=[];
0059 end
0060 
0061 if isempty(head_radius)
0062     fprintf('Estimating the radius of the head by assuming that the center of the head is [0,0,0] in Cartesian coordinates.\n');
0063     dst_from_origin=zeros(1,n_chan);
0064     for a=1:n_chan,
0065         dst_from_origin(a)=sqrt(sum([chanlocs(a).X chanlocs(a).Y chanlocs(a).Z].^2));
0066     end
0067     mn=min(dst_from_origin);
0068     mx=max(dst_from_origin);
0069     md=median(dst_from_origin);
0070     fprintf('Min/Max electrode distance from origin (in chanlocs units): %f/%f\n',mn,mx);
0071     uni=unique(dst_from_origin);
0072     if ((mx-mn)/md)>.001,
0073         fprintf('WARNING: It appears that all electrodes are NOT the same distance from the origin!!!\n');
0074         fprintf('Your electrodes'' Cartesian coordinates either are not spherical or are not centered on [0 0 0].\n');
0075         fprintf('This function will still work properly but its estimate of the radius of the head of will not be correct.\n');
0076     end
0077     head_radius=median(dst_from_origin);
0078     fprintf('Radius of head (in chanlocs units) is estimated to be %f\n',head_radius);
0079 else
0080     fprintf('Using provided head radius of %f (in chanlocs units)\n',head_radius);
0081 end
0082 
0083 circumference=56; %very rough estimate based on the average circumference of 10 Kutaslab participants
0084 max_dist_cm=max_dist*circumference/(2*pi*head_radius); % Radius=Circumference/(2*pi)
0085 
0086 fprintf('max_dist value of %g corresponds to an approximate distance of %.2f cm (assuming\n',max_dist,max_dist_cm);
0087 fprintf('  a 56 cm great circle circumference head and that your electrode coordinates are based on an idealized\n');
0088 fprintf('  spherical head with radius of %f).\n',head_radius);
0089     
0090 chan_hood=zeros(n_chan,n_chan);
0091 n_neighbors=zeros(1,n_chan);
0092 chan_dist=zeros(1,n_chan*(n_chan-1)/2);
0093 ct=0;
0094 for c=1:n_chan,
0095     coordA=[chanlocs(c).X chanlocs(c).Y chanlocs(c).Z];
0096     for d=c:n_chan,
0097         coordB=[chanlocs(d).X chanlocs(d).Y chanlocs(d).Z];
0098         dstnce=sqrt(sum((coordA-coordB).^2));
0099         if dstnce<=max_dist,
0100             chan_hood(c,d)=1;
0101             chan_hood(d,c)=1;
0102         end
0103         
0104         if c~=d
0105             %don't count channels with themselves
0106             ct=ct+1;
0107             chan_dist(ct)=dstnce;
0108         end
0109     end
0110     n_neighbors(c)=sum(chan_hood(c,:))-1;
0111 end
0112 
0113 fprintf('Min/Max distances between all pairs of channels (in chanlocs units): %f/%f\n', ...
0114     min(chan_dist),max(chan_dist));
0115 fprintf('Median (semi-IQR) distance between all pairs of channels (in chanlocs units): %f (%f)\n', ...
0116     median(chan_dist),iqr(chan_dist)/2);
0117 fprintf('Mean (SD) # of neighbors per channel: %.1f (%.1f)\n',mean(n_neighbors), ...
0118     std(n_neighbors));
0119 fprintf('Median (semi-IQR) # of neighbors per channel: %.1f (%.1f)\n',median(n_neighbors), ...
0120     iqr(n_neighbors)/2);
0121 fprintf('Min/max # of neighbors per channel: %d to %d\n',min(n_neighbors), ...
0122     max(n_neighbors));

Generated on Tue 10-May-2016 16:37:45 by m2html © 2005