function test_suite = test_surficial_io_gifti
% tests for GIFTI input/output
%
% # 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_gifti_dataset_io()
if cosmo_skip_test_if_no_external('gifti')
return
end
ds = cosmo_synthetic_dataset('ntargets', 2, 'nchunks', 1, ...
'type', 'surface');
ds.a.fdim.values{1} = 1 + [1 4 7 8 5 3];
encodings = get_gifti_encodings();
orders = get_indexing_orders();
fn = cosmo_make_temp_filename('_tmp', '.gii');
cleaner = onCleanup(@()delete(fn));
% only test subset
ntest = 2;
n_encodings = numel(encodings);
n_orders = numel(orders);
rp = randperm(n_encodings * n_orders);
test_idxs = rp(1:ntest);
counter = 0;
for k = 1:numel(encodings)
encoding = encodings{k};
for j = 1:numel(orders)
counter = counter + 1;
if ~any(test_idxs == counter)
continue
end
order = orders{j};
cosmo_map2surface(ds, fn, 'encoding', encoding);
ds2 = cosmo_surface_dataset(fn);
assert_dataset_equal(ds, ds2);
g_str = get_gifti_string(encoding, order);
fid = fopen(fn, 'w');
fprintf(fid, '%s', g_str);
fclose(fid);
ds3 = cosmo_surface_dataset(fn);
assert_dataset_equal(ds, ds3);
g = gifti(fn);
assertElementsAlmostEqual(double(g.cdata)', ds.samples, ...
'absolute', 1e-5);
node_indices = ds.a.fdim.values{1}(ds.fa.node_indices);
assertEqual(double(g.indices)', node_indices);
g2 = cosmo_map2surface(ds, '-gii');
assertElementsAlmostEqual(g.cdata, g2.cdata, ...
'absolute', 1e-5);
assertEqual(g.indices, g2.indices);
end
end
function assert_dataset_equal(x, y)
assertElementsAlmostEqual(x.samples, y.samples, 'absolute', 1e-5);
assertEqual(sort(fieldnames(x)), sort(fieldnames(y)));
assertEqual(x.fa, y.fa);
assertEqual(x.a, y.a);
function string = get_gifti_string(encoding, indexing_order)
header = get_header();
body = get_data_arrays(encoding, indexing_order);
footer = get_footer();
string = [header body footer];
function string = get_header()
string = sprintf(['<?xml version="1.0" encoding="UTF-8"?>\n'...
'<!DOCTYPE GIFTI SYSTEM "http://gifti.projects.nitr'...
'c.org/gifti.dtd">\n'...
'<GIFTI Version="1.0" NumberOfDataArrays="3">\n'...
' <MetaData>\n'...
' <MD>\n'...
' <Name><![CDATA[UniqueID]]></Name>\n'...
' <Value><![CDATA[XYZ_Uj6iYZUAV3HKbGirxcn-c'...
'A]]></Value>\n'...
' </MD>\n'...
' </MetaData>\n'...
' <LabelTable/>\n' ...
]);
function string = get_footer()
string = '</GIFTI>';
function encodings = get_gifti_encodings()
encodings = {'ASCII', 'Base64Binary', 'GZipBase64Binary'};
function orders = get_indexing_orders()
orders = {'ColumnMajorOrder', 'RowMajorOrder'};
function string = get_data_array_helper(data_str, encoding, data_type, ...
indexing_order, intent)
check_one('encoding', encoding, ...
get_gifti_encodings());
check_one('data_type', data_type, ...
{'NIFTI_TYPE_INT32', 'NIFTI_TYPE_FLOAT32'});
check_one('indexing_order', indexing_order, ...
get_indexing_orders());
string = sprintf([ ...
' <DataArray Intent="%s"\n'...
' DataType="%s"\n'...
' ArrayIndexingOrder="%s"\n'...
' Dimensionality="1"\n'...
' Dim0="6"\n'...
' Encoding="%s"\n'...
' Endian="LittleEndian"\n'...
' ExternalFileName=""\n'...
' ExternalFileOffset="">\n'...
' <MetaData>\n'...
' <MD>\n'...
' <Name><![CDATA[Name]]></Name>\n'...
' <Value><![CDATA[numeric]]></Value>\n'...
' </MD>\n'...
' </MetaData>\n'...
' <Data>\n%s'...
' </Data>\n'...
' </DataArray>\n' ...
], intent, data_type, indexing_order, encoding, data_str);
function string = get_data_arrays(encoding, indexing_order)
switch encoding
case 'ASCII'
data = {sprintf([' 2.031686\n'...
' -3.684948\n'...
' -1.050449\n'...
' 1.349442\n'...
' -0.261723\n'...
' -0.203955\n' ...
]), ...
sprintf([' 0.583806\n'...
' 1.723501\n'...
' -1.326491\n'...
' -0.397334\n'...
' 2.338657\n'...
' 0.482345\n' ...
]), ...
sprintf([' 1 \n'...
' 4 \n'...
' 7 \n'...
' 8 \n'...
' 5 \n'...
' 3 \n' ...
])};
case 'Base64Binary'
data = {'JQcCQDDWa8AddYa/hLqsP48Ahr6U2VC+', ...
'T3QVP66b3D91yqm/XW/Lvo6sFUDt9fY+', ...
'AQAAAAQAAAAHAAAACAAAAAUAAAADAAAA' ...
};
case 'GZipBase64Binary'
data = { 'eAEBGADn/yUHAkAw1mvAHXWGv4S6rD+PAIa+lNlQvnPfCu4=', ...
'eAEBGADn/090FT+um9w/dcqpv11vy76OrBVA7fX2PpcYDR0=', ...
'eAEBGADn/wEAAAAEAAAABwAAAAgAAAAFAAAAAwAAAAGEAB0=' ...
};
end
narrays = numel(data);
arrays_cell = cell(1, narrays);
data_types = {'NIFTI_TYPE_FLOAT32', ...
'NIFTI_TYPE_FLOAT32', ...
'NIFTI_TYPE_INT32' ...
};
intents = {'NIFTI_INTENT_NONE', ...
'NIFTI_INTENT_NONE', ...
'NIFTI_INTENT_NODE_INDEX'};
assert(numel(data_types) == narrays);
assert(numel(intents) == narrays);
for k = 1:narrays
arrays_cell{k} = get_data_array_helper(data{k}, encoding, ...
data_types{k}, ...
indexing_order, intents{k});
end
string = cat(2, arrays_cell{:});
function check_one(label, value, allowed)
if isempty(strmatch(value, allowed))
error('illegal value for %s: %s', label, value);
end