function neighbors=cosmo_meeg_chan_neighbors(ds, varargin)
% find neighbors of MEEG channels
%
% neighbors=cosmo_meeg_chan_neighbors(ds, ...)
%
% Inputs:
% ds MEEG dataset struct
% 'label', lab Labels to return in output, one of:
% 'layout' : determine neighbors based on layout
% associated with ds (default). All
% labels in the layout are used as
% center labels.
% 'dataset' : determine neighbors based on labels
% present in ds. Only labels present in
% ds are used as center labels
% {x1,...,xn} : use labels x1 ... xn
% 'chantype', tp (optional) channel type of neighbors, can be one of
% 'eeg', 'meg_planar', 'meg_axial', or
% 'meg_combined_from_planar'.
% Use 'all' to use all channel types associated with
% lab, and 'all_combined' to use
% 'meg_combined_from_planar' with all other channel
% types in ds except for 'meg_planar'.
% If there is only one channel type associated with
% lab, then this argument is not required.
% 'radius', r } select neighbors either within radius r, grow
% 'count', c } the radius to get neighbors are c locations,
% 'delaunay', true } or use Delaunay triangulation to find direct
% } neighbors for each channel.
% } These three options are mutually exclusive
%
%
% Output:
% neighbors Kx1 struct for K center labels, with fields:
% .label center label
% .neighblabel cell with labels of neighbors
%
% Examples:
% % (This example requires FieldTrip)
% cosmo_skip_test_if_no_external('fieldtrip');
% %
% % get neighbors within radius of .3 for EEG dataset
% ds=cosmo_synthetic_dataset('type','meeg',...
% 'sens','eeg1010','size','big');
% % show all channel labels
% cosmo_disp(ds.a.fdim.values{1});
% %|| { 'TP10' 'TP7' 'TP8' ... 'A2' 'M1' 'M2' }@1x94
% %
% % simulate the case where some channels are missing; here, every 7-th
% % channels is removed
% ds=cosmo_slice(ds,mod(ds.fa.chan,7)~=2,2);
% ds=cosmo_dim_prune(ds);
% %
% % show remaining channel labels
% cosmo_disp(ds.a.fdim.values{1});
% %|| { 'TP10' 'TP8' 'TP9' ... 'A1' 'A2' 'M2' }@1x80
% %
% % get neighbors for the channel layout associated with this
% % dataset. This layout ('EEG1010.lay') has 88 channel positions,
% % of which the last two are ignored because they are 'COMNT' and
% % 'SCALE'
% nbrs=cosmo_meeg_chan_neighbors(ds,'radius',.3);
% cosmo_disp(nbrs,'edgeitems',1);
% %|| <struct>@86x1
% %|| (1,1) .label
% %|| 'Fp1'
% %|| .neighblabel
% %|| { 'Fp1'
% %|| :
% %|| 'FC1' }@21x1
% %|| : :
% %|| (86,1).label
% %|| 'I2'
% %|| .neighblabel
% %|| { 'P4'
% %|| :
% %|| 'I2' }@16x1
% %
% % since the dataset has only 80 channels, 74 of which are in the
% % layout, using the dataset's labels only (with the 'labels'
% % argument) returns
% % only neighbors for channels in the dataset
% nbrs=cosmo_meeg_chan_neighbors(ds,'radius',.3,...
% 'label','dataset');
% cosmo_disp(nbrs,'edgeitems',1);
% %|| <struct>@74x1
% %|| (1,1) .label
% %|| 'Fp1'
% %|| .neighblabel
% %|| { 'Fp1'
% %|| :
% %|| 'FC1' }@21x1
% %|| : :
% %|| (74,1).label
% %|| 'I2'
% %|| .neighblabel
% %|| { 'P4'
% %|| :
% %|| 'I2' }@16x1
%
% % (This example requires FieldTrip)
% cosmo_skip_test_if_no_external('fieldtrip');
% %
% % get neighbors at 4 neighboring sensor location for
% % planar neuromag306 channels
% ds=cosmo_synthetic_dataset('type','meeg','size','big');
% nbrs=cosmo_meeg_chan_neighbors(ds,...
% 'chantype','meg_planar','count',4);
% cosmo_disp(nbrs,'edgeitems',1);
% %|| <struct>@204x1
% %|| (1,1) .label
% %|| 'MEG0113'
% %|| .neighblabel
% %|| { 'MEG0113'
% %|| 'MEG0112'
% %|| 'MEG0122'
% %|| 'MEG0133' }
% %|| : :
% %|| (204,1).label
% %|| 'MEG2643'
% %|| .neighblabel
% %|| { 'MEG2423'
% %|| 'MEG2422'
% %|| 'MEG2642'
% %|| 'MEG2643' }
%
% % (This example requires FieldTrip)
% cosmo_skip_test_if_no_external('fieldtrip');
% %
% % get neighbors at 4 neighboring sensor location for
% % planar neuromag306 channels, but with the center labels
% % the set of combined planar channels
% % (there are 8 channels in the .neighblabel fields, because
% % there are two planar channels per combined channel)
% ds=cosmo_synthetic_dataset('type','meeg','size','big');
% nbrs=cosmo_meeg_chan_neighbors(ds,...
% 'chantype','meg_combined_from_planar','count',4);
% cosmo_disp(nbrs,'edgeitems',1);
% %|| <struct>@102x1
% %|| (1,1) .label
% %|| 'MEG0112+0113'
% %|| .neighblabel
% %|| { 'MEG0112'
% %|| :
% %|| 'MEG0343' }@8x1
% %|| : :
% %|| (102,1).label
% %|| 'MEG2642+2643'
% %|| .neighblabel
% %|| { 'MEG2422'
% %|| :
% %|| 'MEG2643' }@8x1
%
% % (This example requires FieldTrip)
% cosmo_skip_test_if_no_external('fieldtrip');
% %
% % As above, but now use both the axial and planar channels.
% % Here the axial channels only have axial neighbors, and the planar
% % channels only have planar neighbors
% ds=cosmo_synthetic_dataset('type','meeg','size','big');
% nbrs=cosmo_meeg_chan_neighbors(ds,...
% 'chantype','all','count',4);
% cosmo_disp(nbrs,'edgeitems',1);
% %|| <struct>@306x1
% %|| (1,1) .label
% %|| 'MEG0111'
% %|| .neighblabel
% %|| { 'MEG0111'
% %|| 'MEG0121'
% %|| 'MEG0131'
% %|| 'MEG0341' }
% %|| : :
% %|| (306,1).label
% %|| 'MEG2643'
% %|| .neighblabel
% %|| { 'MEG2423'
% %|| 'MEG2422'
% %|| 'MEG2642'
% %|| 'MEG2643' }
%
% % (This example requires FieldTrip)
% cosmo_skip_test_if_no_external('fieldtrip');
% %
% % As above, but now use both the axial and planar channels with
% % center labels for the planar channels from the combined_planar set.
% % Here the axial center channels have 4 axial neighbors each, while
% % the planar_combined channels have 8 planar (uncombined) neigbors
% % each.
% ds=cosmo_synthetic_dataset('type','meeg','size','big');
% nbrs=cosmo_meeg_chan_neighbors(ds,...
% 'chantype','all_combined','count',4);
% cosmo_disp(nbrs,'edgeitems',1);
% %|| <struct>@204x1
% %|| (1,1) .label
% %|| 'MEG0111'
% %|| .neighblabel
% %|| { 'MEG0111'
% %|| 'MEG0121'
% %|| 'MEG0131'
% %|| 'MEG0341' }
% %|| : :
% %|| (204,1).label
% %|| 'MEG2642+2643'
% %|| .neighblabel
% %|| { 'MEG2422'
% %|| :
% %|| 'MEG2643' }@8x1
%
%
% Notes:
% - this function returns a struct similar to FieldTrip's
% ft_prepare_neighbors, but not identical:
% * a center labels can be a neighbor of itself
% * the neighbors are similar but not identical to FieldTrip's
% ft_prepare_neighbors
% - for searchlight and clustering purposes, use
% cosmo_meeg_chan_neighborhood
%
% See also: cosmo_meeg_chantype, ft_prepare_neighbours,
% cosmo_meeg_chan_neighborhood
%
% # For CoSMoMVPA's copyright information and license terms, #
% # see the COPYING file distributed with CoSMoMVPA. #