function test_suite=test_meeg_layout_collection
% tests for cosmo_meeg_layout_collection
%
% # For CoSMoMVPA's copyright information and license terms, #
% # see the COPYING file distributed with CoSMoMVPA. #
try % assignment of 'localfunctions' is necessary in Matlab >= 2016
test_functions=localfunctions();
catch % no problem; early Matlab versions can use initTestSuite fine
end
initTestSuite;
function test_fieldtrip_correspondence
if cosmo_skip_test_if_no_external('fieldtrip')
return;
end
lc=cosmo_meeg_layout_collection();
rp_lay=randperm(numel(lc));
ntest_layout=2;
ntest_chan_max=10;
% may or may not be present
ignore_labels={'COMNT','SCALE'};
% temporarily switch off warnings (emitted by fieldtrip)
warning_state=warning('query','all');
cleaner=onCleanup(@()warning(warning_state));
warning('off','all');
% shorter form
tolerance=1e-4;
aeae=@(x,y)max(abs(x(:)-y(:)))<tolerance && isequal(size(x),size(y));
for ii=1:ntest_layout
layout=lc{rp_lay(ii)};
cfg=struct();
cfg.layout=layout.name;
layout_ft=ft_prepare_layout(cfg);
% test outlnie
for j=1:max(numel(layout_ft.outline),numel(layout.outline))
aeae(layout_ft.outline{j},layout.outline{j});
end
% test mask
for j=1:max(numel(layout_ft.mask),numel(layout.mask))
aeae(layout_ft.outline{j},layout.outline{j});
end
% test labels
keep_idxs=find(~cosmo_match(layout.label,ignore_labels));
keep_ft_idxs=find(~cosmo_match(layout_ft.label,ignore_labels));
assertEqual(sort(layout.label(keep_idxs)),...
sort(layout_ft.label(keep_ft_idxs)));
% test positions
ntest_chan=min(numel(keep_idxs),ntest_chan_max);
rp_chan=randperm(numel(keep_idxs));
for jj=1:ntest_chan
test_label_idx=keep_idxs(rp_chan(jj));
label=layout.label{test_label_idx};
if strcmp(layout_ft.label{test_label_idx},label)
% little optimization
pos=test_label_idx;
else
pos=find(cosmo_match(layout_ft.label,{label}));
assert(numel(pos)==1);
end
aeae(layout_ft.width(pos,:),layout.width(test_label_idx,:));
aeae(layout_ft.height(pos,:),layout.height(test_label_idx,:));
aeae(layout_ft.pos(pos,:),layout.pos(test_label_idx,:));
end
end
function test_meeg_layout_collection_
if cosmo_skip_test_if_no_external('fieldtrip')
return;
end
% get layout properties
% order is:
% - layout name
% - number of channels
% - some channel positions
% - labels of channel positions
lay_props=get_layout_properties();
% test each one
n=numel(lay_props);
clear('cosmo_meeg_layout_collection');
lc=cosmo_meeg_layout_collection();
lc_cached=cosmo_meeg_layout_collection();
assertEqual(lc,lc_cached);
lc_names=cellfun(@(x) x.name,lc,'UniformOutput',false);
for k=1:n
lay_prop=lay_props{k};
name=lay_prop{1};
nchan=lay_prop{2};
pos=lay_prop{3};
label=lay_prop{4};
i=find(cosmo_match(lc_names,name));
assertEqual(numel(i),1);
lay=lc{i};
keep=find(~cosmo_match(lay.label,{'COMNT','SCALE'}));
assertEqual(numel(keep),nchan);
for j=1:numel(label)
lab_i=find(cosmo_match(lay.label,label{j}));
assert(numel(lab_i)==1);
assertElementsAlmostEqual(lay.pos(lab_i,:),pos(j,:),...
'absolute',1e-4);
end
end
function lay_props=get_layout_properties()
% the layout properties below were generated with the following code:
% names={'yokogawa440.lay', 'neuromag306planar.lay',...
% 'neuromag306mag.lay', 'neuromag306cmb.lay',...
% 'neuromag306all.lay', 'elec1020.lay',...
% 'elec1010.lay', 'elec1005.lay', 'biosemi32.lay',...
% 'biosemi128.lay', 'biosemi256.lay', 'EEG1020.lay',...
% 'EEG1010.lay', 'EEG1005.lay', 'CTF151.lay',...
% 'CTF275.lay', '4D148.lay', '4D248.lay'};
% lc=cosmo_meeg_layout_collection();
% lcn=cellfun(@(x) x.name,lc,'UniformOutput',false);
% for k=1:numel(names)
% fn=[names{k}];
% m=find(cosmo_match(lcn,fn));
% lay=lc{m};
% keep=find(~cosmo_match(lay.label,{'COMNT','SCALE'}));
% nch=numel(keep);
% desc=sprintf(['{''%s'',%d,...\n\t\t\t[%.4f %.4f;%.4f %.4f],'...
% '...\n\t\t\t{''%s'',''%s''}},...'],...
% lay.name,nch,lay.pos(keep([1 end]),:)',...
% lay.label{keep(1)},lay.label{keep(end)});
% fprintf('%s\n',desc);
% end
lay_props={ {'4D248.lay',248,...
[0.0038 0.0232;0.3897 0.3453],...
{'A1','A248'}},...
{'yokogawa440.lay',440,...
[-0.3337 0.3729;-0.0108 0.0726],...
{'AG001','AG440'}},...
{'neuromag306planar.lay',204,...
[-0.4084 0.2532;0.3733 -0.0820],...
{'MEG0113','MEG2643'}},...
{'neuromag306mag.lay',102,...
[-0.4084 0.2732;0.3733 -0.1036],...
{'MEG0111','MEG2641'}},...
{'neuromag306cmb.lay',102,...
[-0.4084 0.2732;0.3733 -0.1036],...
{'MEG0112+0113','MEG2642+2643'}},...
{'neuromag306all.lay',306,...
[-0.4099 0.2532;0.3761 -0.0976],...
{'MEG0113','MEG2641'}},...
{'elec1020.lay',21,...
[-0.1710 0.4010;0.1710 -0.4010],...
{'Fp1','O2'}},...
{'elec1010.lay',86,...
[-0.1112 0.4261;0.1391 -0.4257],...
{'Fp1','I2'}},...
{'elec1005.lay',335,...
[-0.1112 0.3881;0.1252 -0.3814],...
{'Fp1','OI2'}},...
{'biosemi32.lay',32,...
[-0.1391 0.4500;0.0000 0.0113],...
{'Fp1','Cz'}},...
{'biosemi128.lay',128,...
[0.0000 0.0500;-0.4096 -0.2145],...
{'A1','D32'}},...
{'biosemi256.lay',256,...
[0.0000 0.0587;-0.2290 -0.4060],...
{'A1','H32'}},...
{'EEG1020.lay',21,...
[-0.1390 0.4280;0.1390 -0.4280],...
{'Fp1','O2'}},...
{'EEG1010.lay',86,...
[-0.1112 0.4260;0.1390 -0.4256],...
{'Fp1','I2'}},...
{'EEG1005.lay',335,...
[-0.1112 0.3880;0.1252 -0.3814],...
{'Fp1','OI2'}},...
{'CTF151.lay',151,...
[-0.0344 0.1732;0.0008 -0.2668],...
{'MLC11','MZP02'}},...
{'CTF275.lay',275,...
[-0.0171 0.1815;0.0002 -0.2056],...
{'MLC11','MZP01'}},...
{'4D148.lay',148,...
[-0.0109 0.0939;0.3709 0.3364],...
{'A1','A148'}},...
{'4D248.lay',248,...
[0.0038 0.0232;0.3897 0.3453],...
{'A1','A248'}}};