function test_suite = test_fmri_dataset()
% tests for cosmo_fmri_dataset
%
% # 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_base_fmri_dataset()
ds=get_base_dataset();
assert_dataset_equal(ds, get_expected_dataset());
function test_afni_fmri_dataset()
if cosmo_skip_test_if_no_external('afni')
return;
end
ds=get_base_dataset();
afni=cosmo_map2fmri(ds,'-afni');
afni_expected=get_expected_afni();
assertAlmostEqualWithTol(afni.img, afni_expected.img);
afni_no_img=rmfield(afni,'img');
afni_expected_no_img=rmfield(afni_expected,'img');
assertEqual(afni_no_img,afni_expected_no_img);
ds_afni=cosmo_fmri_dataset(afni);
assert_dataset_equal(ds,ds_afni);
function test_nii_sform_fmri_dataset()
ds=get_base_dataset();
nii=cosmo_map2fmri(ds,'-nii');
nii_expected=get_expected_nii_sform();
assertEqual(nii.hdr, nii_expected.hdr);
assertAlmostEqualWithTol(nii.img,nii_expected.img);
ds_nii=cosmo_fmri_dataset(nii);
assert_dataset_equal(ds,ds_nii);
function test_nii_qform_fmri_dataset()
ds=get_base_dataset();
nii=get_expected_nii_qform();
ds_nii=cosmo_fmri_dataset(nii);
assert_dataset_equal(ds,ds_nii);
% check qform with illegal pixdims
nii.hdr.dime.pixdim(1:4)=-1;
nii.hdr.hist.quatern_b=1;
nii.hdr.hist.quatern_c=0;
nii.hdr.hist.quatern_d=0;
ds_nii_alt=cosmo_fmri_dataset(nii);
m=ds_nii_alt.a.vol.mat;
assertEqual(diag(m),[1 -1 1 1]');
assertEqual(m(1:3,4),[-2 0 -2]');
function test_nii_pixdim_fmri_dataset()
ds=get_base_dataset();
nii=get_expected_nii_pixdim();
ds_nii=cosmo_fmri_dataset(nii);
ds_nii.a.vol.mat(:,4)=ds.a.vol.mat(:,4);
assert_dataset_equal(ds,ds_nii);
nii.hdr.dime.scl_inter=200;
nii.hdr.dime.scl_slope=17;
ds_nii_scl=cosmo_fmri_dataset(nii);
assertElementsAlmostEqual(17*ds.samples+200,ds_nii_scl.samples,...
'absolute',1e-3);
function test_nii_sform_afni_5d_singleton_dataset()
ds=get_base_dataset();
nii=get_expected_nii_sform();
% header: move 4th to 5th dimension
nii.hdr.dime.dim(6)=nii.hdr.dime.dim(5);
nii.hdr.dime.dim(5)=1;
% data: move 4th to 5th dimension
orig_size=size(nii.img);
nii.img=reshape(nii.img,[orig_size(1:3) 1 orig_size(4)]);
% test this test: verify size is ok
assertEqual(nii.hdr.dime.dim(2:6),size(nii.img));
ds_nii=cosmo_fmri_dataset(nii);
assert_dataset_equal(ds,ds_nii);
function test_nii_sform_afni_5d_nonsingleton_dataset()
ds=get_base_dataset();
nii=get_expected_nii_sform();
% header: add extra dimension
nrep=ceil(rand()*3+2);
nii.hdr.dime.dim(6)=nrep;
% data: move 4th to 5th dimension
img_rep=repmat({nii.img},1,nrep);
nii.img=cat(5,img_rep{:});
% test this test: verify size is ok
assertEqual(nii.hdr.dime.dim(2:6),size(nii.img));
% must not support this
assertExceptionThrown(@()cosmo_fmri_dataset(nii),'');
function test_nii_sform_and_qform_fmri_dataset()
ds=get_base_dataset();
nii=get_expected_nii_sform_and_qform();
ds_nii=cosmo_fmri_dataset(nii);
assert_dataset_equal(ds,ds_nii);
nii.hdr.hist.srow_x(1)=1;
assertExceptionThrown(@()cosmo_fmri_dataset(nii),'');
ds_nii_qform=cosmo_fmri_dataset(nii,'nifti_form','qform');
assertEqual(ds_nii_qform,ds_nii);
assertExceptionThrown(@()cosmo_fmri_dataset(nii,'nifti_form','X'),'');
function test_bv_vmr_fmri_dataset()
if ~can_test_bv()
return
end
uint_ds=get_uint8_dataset();
bv_vmr=cosmo_map2fmri(uint_ds,'-bv_vmr');
cleaner=onCleanup(@()bv_vmr.ClearObject());
neuroelf_bless_wrapper(bv_vmr);
assert_bv_equal(bv_vmr, get_expected_bv_vmr());
ds_bv_vmr=cosmo_fmri_dataset(bv_vmr,'mask',false);
ds_bv_vmr_lpi=cosmo_fmri_reorient(ds_bv_vmr,'LPI');
assert_dataset_equal(uint_ds,ds_bv_vmr_lpi,'rotation');
function test_bv_vmp_fmri_dataset()
if ~can_test_bv()
return
end
ds=get_base_dataset();
bv_vmp=cosmo_map2fmri(ds,'-bv_vmp');
cleaner=onCleanup(@()bv_vmp.ClearObject());
neuroelf_bless_wrapper(bv_vmp);
assert_bv_equal(bv_vmp, get_expected_bv_vmp());
ds_bv_vmp=cosmo_fmri_dataset(bv_vmp);
ds_bv_vmp_lpi=cosmo_fmri_reorient(ds_bv_vmp,'LPI');
assert_dataset_equal(ds,ds_bv_vmp_lpi,'translation');
function test_bv_msk_fmri_dataset()
if ~can_test_bv()
return
end
uint_ds=get_uint8_dataset();
bv_msk=cosmo_map2fmri(uint_ds,'-bv_msk');
cleaner=onCleanup(@()bv_msk.ClearObject());
neuroelf_bless_wrapper(bv_msk);
assert_bv_equal(bv_msk, get_expected_bv_msk());
ds_bv_msk=cosmo_fmri_dataset(bv_msk,'mask',false);
ds_bv_msk_lpi=cosmo_fmri_reorient(ds_bv_msk,'LPI');
assert_dataset_equal(uint_ds,ds_bv_msk_lpi,'translation');
function test_bv_vtc_fmri_dataset()
if ~can_test_bv()
return
end
ds=get_base_dataset();
ds.samples=round(ds.samples);
ds.samples(ds.samples<0)=0;
xff_bv_vtc=get_expected_xff_bv_vtc();
cleaner=onCleanup(@()xff_bv_vtc.ClearObject());
neuroelf_bless_wrapper(xff_bv_vtc);
ds_bv_vtc=cosmo_fmri_dataset(xff_bv_vtc);
ds_bv_glm_lpi=cosmo_fmri_reorient(ds_bv_vtc,'LPI');
assert_dataset_equal(ds,ds_bv_glm_lpi,'translation');
function test_bv_glm_subject_fmri_dataset()
if ~can_test_bv()
return
end
% no support for map2fmri, so just test with neuroelf struct
ds=get_base_dataset();
xff_bv_glm=get_expected_xff_bv_glm();
cleaner=onCleanup(@()xff_bv_glm.ClearObject());
neuroelf_bless_wrapper(xff_bv_glm);
ds_bv_glm=cosmo_fmri_dataset(xff_bv_glm);
ds_bv_glm_lpi=cosmo_fmri_reorient(ds_bv_glm,'LPI');
assert_dataset_equal(ds,ds_bv_glm_lpi,'translation');
function test_mask_fmri_dataset()
aet=@(varargin)assertExceptionThrown(@()...
cosmo_fmri_dataset(varargin{:}),'');
ds=cosmo_synthetic_dataset();
ds.samples(:,[2 6])=0;
x=cosmo_fmri_dataset(ds,'mask','-auto');
assertEqual(x,cosmo_slice(ds,[1 3 4 5],2));
x1=cosmo_fmri_dataset(ds,'mask',true);
assertEqual(x1,x);
x2=cosmo_fmri_dataset(ds,'mask',false);
assertEqual(x2,ds);
aet(ds,'mask','foo');
aet(ds,'mask','-foo');
aet(ds,'mask',ds);
aet(ds,'mask',struct);
ds.samples(1,2)=1;
aet(ds,'mask','-auto');
x3=cosmo_fmri_dataset(ds,'mask','-any');
assertEqual(x3,x);
x4=cosmo_fmri_dataset(ds,'mask','-all');
assertEqual(x4,cosmo_slice(ds,[1 2 3 4 5],2));
msk_ds=cosmo_slice(cosmo_slice(x,randperm(size(x.samples,2)),2),1);
x5=cosmo_fmri_dataset(ds,'mask',msk_ds);
assertEqual(x5,x);
function test_pymvpa_fmri_dataset()
pymvpa_ds=get_pymvpa_dataset();
ds=cosmo_fmri_dataset(pymvpa_ds);
assert_dataset_equal(ds, get_expected_dataset(), 'translation');
function test_pymvpa_3d_string_array()
py_ds=get_pymvpa_dataset();
sa_labels={'foo';'bar'};
sa_labels_3d=reshape(strvcat(sa_labels),[2 1 3]);
py_ds.sa.labels=sa_labels_3d;
fa_labels={'foox','barx','foobazx','1','2','3'};
fa_labels_3d=reshape(strvcat(fa_labels),[1 6 7]);
py_ds.fa.labels=fa_labels_3d;
ds=cosmo_fmri_dataset(py_ds);
assertEqual(ds.sa.labels,sa_labels);
assertEqual(ds.fa.labels,fa_labels);
function test_meeg_source_fmri_dataset()
ds=cosmo_synthetic_dataset('type','source');
res=cosmo_fmri_dataset(ds);
assertEqual(ds.samples,res.samples);
assertEqual(diag(res.a.vol.mat),[10 10 10 1]');
function test_set_sa_fmri_dataset()
ds=cosmo_synthetic_dataset();
res=cosmo_fmri_dataset(ds,'targets',1:6,'chunks',3);
assertEqual(res.sa.targets,(1:6)');
assertEqual(res.sa.chunks,ones(6,1)*3);
assertExceptionThrown(@()cosmo_fmri_dataset(ds,'targets',[1 2]),'');
function test_nan_warning_fmri_dataset()
ds=cosmo_synthetic_dataset();
ds.samples(1)=NaN;
msk_ds=cosmo_slice(ds,2);
orig_warning_state=cosmo_warning();
warning_state_resetter=onCleanup(@()cosmo_warning(orig_warning_state));
cosmo_warning('off');
cosmo_fmri_dataset(ds,'mask',msk_ds);
warning_state=cosmo_warning();
warning_pos=strmatch('The input dataset has NaN',...
warning_state.shown_warnings);
assert(~isempty(warning_pos));
function tf=can_test_bv()
tf=~cosmo_skip_test_if_no_external('neuroelf');
function ds=get_base_dataset()
ds=cosmo_synthetic_dataset('ntargets',2,'nchunks',1);
function ds=get_uint8_dataset()
ds=cosmo_synthetic_dataset('ntargets',2,'nchunks',1);
ds=cosmo_slice(ds,1);
mn=min(ds.samples);
mx=max(ds.samples);
ds.samples=uint8((ds.samples-mn)/(mx-mn)*255);
function ds=get_pymvpa_dataset()
ds=cosmo_synthetic_dataset('ntargets',2,'nchunks',1);
% set .a
ds.a.imgaffine=ds.a.vol.mat;
ds.a.imgaffine(1:3,4)=ds.a.imgaffine(1:3,4)+...
ds.a.imgaffine(1:3,1:3)*ones(3,1);
ds.a.voxel_eldim=single([3 3]);
ds.a.voxel_dim=int64(ds.a.vol.dim(:));
ds.a=rmfield(ds.a,'vol');
ds.a=rmfield(ds.a,'fdim');
% set .fa
voxel_indices=int64([ds.fa.i; ds.fa.j; ds.fa.k]-1);
ds.fa=struct();
ds.fa.voxel_indices=voxel_indices;
% set .samples
ds.samples=single(ds.samples);
function assertAlmostEqualWithTol(x,y)
assertElementsAlmostEqual(double(x),double(y),'relative',1e-3);
function assert_dataset_equal(x,y,opt)
if nargin<3 || isempty(opt)
opt='';
end
% dataset equality, without .sa
assertAlmostEqualWithTol(x.samples, y.samples);
assertEqual(x.fa, y.fa)
switch opt
case 'rotation'
% BV VMR cannot store orientation, just check the rotation part
assertEqual(x.a.fdim, y.a.fdim);
assertAlmostEqualWithTol(x.a.vol.dim,y.a.vol.dim);
assertAlmostEqualWithTol(x.a.vol.mat(1:3,1:3),...
y.a.vol.mat(1:3,1:3));
case 'translation'
% BV VMP or PyMVPA cannot store xform, just check the matrix
assertEqual(x.a.fdim, y.a.fdim);
assertAlmostEqualWithTol(x.a.vol.dim,y.a.vol.dim);
assertAlmostEqualWithTol(x.a.vol.mat,y.a.vol.mat);
otherwise
assertEqual(x.a, y.a)
end
function assert_bv_equal(x_xff, y_struct)
% BV equality; first argument is xff class, second argument a struct
% passes if all fields in y_struct have the same value in x_xff;
% x_xff can have more fields than y_struct
keys=fieldnames(y_struct);
for k=1:numel(keys)
key=keys{k};
y=y_struct.(key);
x=x_xff.(key);
if isstruct(x)
for j=1:numel(x)
assert_bv_equal(x(j),y(j))
end
else
assertAlmostEqualWithTol(x,y);
end
end
function xff_bv_glm=get_expected_xff_bv_glm()
xff_bv_glm=xff('new:glm');
xff_bv_glm.NrOfSubjects=1;
xff_bv_glm.NrOfPredictors=2;
xff_bv_glm.Predictor=struct('Name1',{'1','2'},...
'Name2',{'1','2'},...
'RGB',{[255 0 0] [0 255 0]});
xff_bv_glm.Resolution=2;
xff_bv_glm.XStart = 127;
xff_bv_glm.XEnd = 131;
xff_bv_glm.YStart = 129;
xff_bv_glm.YEnd = 131;
xff_bv_glm.ZStart = 125;
xff_bv_glm.ZEnd = 131;
data=zeros(2,1,3,2);
data_size=size(data);
mat_size=data_size(1:3);
data(:,:,:,1)=reshape([ -0.2040 -1.0504 -0.2617 ...
-3.6849 1.3494 2.0317], mat_size);
data(:,:,:,2)=reshape([0.4823 -1.3265 2.3387 ...
1.7235 -0.3973 0.5838], mat_size);
xff_bv_glm.GLMData.BetaMaps=data;
function xff_bv_vtc=get_expected_xff_bv_vtc()
xff_bv_vtc=xff('new:vtc');
xff_bv_vtc.NrOfVolumes=2;
xff_bv_vtc.Resolution=2;
xff_bv_vtc.XStart = 127;
xff_bv_vtc.XEnd = 131;
xff_bv_vtc.YStart = 129;
xff_bv_vtc.YEnd = 131;
xff_bv_vtc.ZStart = 125;
xff_bv_vtc.ZEnd = 131;
data_orig=zeros(2,1,3,2);
data_size=size(data_orig);
mat_size=data_size(1:3);
data_orig(:,:,:,1)=reshape([ -0.2040 -1.0504 -0.2617 ...
-3.6849 1.3494 2.0317], mat_size);
data_orig(:,:,:,2)=reshape([0.4823 -1.3265 2.3387 ...
1.7235 -0.3973 0.5838], mat_size);
data=uint16(data_orig);
xff_bv_vtc.VTCData=zeros(2,2,1,3,'uint16');
xff_bv_vtc.VTCData(1,:,:,:)=data(:,:,:,1);
xff_bv_vtc.VTCData(2,:,:,:)=data(:,:,:,2);
function bv_msk=get_expected_bv_msk()
bv_msk=struct();
bv_msk.Resolution= 2 ;
bv_msk.XStart = 127;
bv_msk.XEnd = 131;
bv_msk.YStart = 129;
bv_msk.YEnd = 131;
bv_msk.ZStart = 125;
bv_msk.ZEnd = 131;
data=zeros(2,1,3,'uint8');
data(:,:,1) = [ 155 118 ];
data(:,:,2) = [ 153 0 ];
data(:,:,3) = [ 225 255 ];
bv_msk.Mask=data;
function bv_vmp=get_expected_bv_vmp()
bv_vmp=struct();
bv_vmp.NrOfMaps = 2;
bv_vmp.OverallMapType = 1;
bv_vmp.OverallNrOfLags = [];
bv_vmp.NrOfTimePoints = 0;
bv_vmp.NrOfMapParameters = 0;
bv_vmp.ShowParamsRangeFrom = 0;
bv_vmp.ShowParamsRangeTo = 0;
bv_vmp.FingerprintParamsRangeFrom = 0;
bv_vmp.FingerprintParamsRangeTo = 0;
bv_vmp.Resolution = 2;
bv_vmp.XStart = 127;
bv_vmp.XEnd = 131;
bv_vmp.YStart = 129;
bv_vmp.YEnd = 131;
bv_vmp.ZStart = 125;
bv_vmp.ZEnd = 131;
map1.VMPData=reshape([-0.2040 -1.0504 -0.2617 ...
-3.6849 1.3494 2.0317],[2 1 3]);
map2.VMPData=reshape([0.4823 -1.3265 2.3387 ...
1.7235 -0.3973 0.5838],[2 1 3]);
bv_vmp.Map=cat(1,map1,map2);
function bv_vmr=get_expected_bv_vmr()
bv_vmr=struct();
bv_vmr.FileVersion = 3;
bv_vmr.DimX = 2;
bv_vmr.DimY = 1;
bv_vmr.DimZ = 3;
bv_vmr.VMRData16 = [];
bv_vmr.OffsetX = 0;
bv_vmr.OffsetY = 0;
bv_vmr.OffsetZ = 0;
bv_vmr.FramingCube = 256;
bv_vmr.PosInfoVerified = false;
bv_vmr.RowDirX = 0;
bv_vmr.RowDirY = 1;
bv_vmr.RowDirZ = 0;
bv_vmr.ColDirX = 0;
bv_vmr.ColDirY = 0;
bv_vmr.ColDirZ = -1;
bv_vmr.NRows = 256;
bv_vmr.NCols = 256;
bv_vmr.FoVRows = 256;
bv_vmr.FoVCols = 256;
bv_vmr.SliceThickness = 1;
bv_vmr.GapThickness = 0;
bv_vmr.ReferenceSpace = 0;
bv_vmr.VoxResX = 2;
bv_vmr.VoxResY = 2;
bv_vmr.VoxResZ = 2;
bv_vmr.VoxResInTalairach = false;
bv_vmr.VoxResVerified = false;
data=zeros(2,1,3,'uint8');
data(:,:,1) = [ 155 118 ];
data(:,:,2) = [ 153 0 ];
data(:,:,3) = [ 225 255 ];
bv_vmr.VMRData=data;
function afni=get_expected_afni()
% header
afni=struct();
afni.SCENE_DATA = [ 0 11 1 ];
afni.TYPESTRING = '3DIM_HEAD_FUNC' ;
afni.BRICK_TYPES = [ 3 3 ];
afni.BRICK_STATS = [];
afni.BRICK_FLOAT_FACS = [ ];
afni.DATASET_RANK = [ 3 2 ];
afni.DATASET_DIMENSIONS = [ 3 2 1 ];
afni.ORIENT_SPECIFIC = [ 1 2 4 ];
afni.DELTA = [ -2 -2 2 ];
afni.ORIGIN = [ 1 1 -1 ];
afni.SCALE = 0;
afni.BRICK_LABS = [];
afni.BRICK_KEYWORDS = [];
afni.BRICK_STATAUX = [];
afni.STAT_AUX = [];
afni.SCALE=0;
afni.NOTES_COUNT=0;
afni.WARP_TYPE=[0 0];
afni.FileFormat='BRIK';
[unused, unused, endian_ness] = computer();
afni.BYTEORDER_STRING = sprintf('%sSB_FIRST',endian_ness );
% data
data=zeros(3,2,1,2);
data(:,:,1,1)=[ 2.0317 1.3494;-3.6849 -0.2617;-1.0504 -0.2040];
data(:,:,1,2)=[ 0.5838 -0.3973; 1.7235 2.3387;-1.3265 0.4823];
% add to image
afni.img=data;
function ds=get_expected_dataset()
ds=struct();
ds.samples=[ 2.0317 -3.6849 -1.0504 1.3494 -0.2617 -0.2040;
0.5838 1.7235 -1.3265 -0.3973 2.3387 0.4823];
ds.fa.i=[1 2 3 1 2 3];
ds.fa.j=[1 1 1 2 2 2];
ds.fa.k=[1 1 1 1 1 1];
ds.a.fdim.labels={'i';'j';'k'};
ds.a.fdim.values={[1 2 3];[1 2];1};
mat=diag([2 2 2 1]);
mat(1:3,4)=-3;
ds.a.vol.mat=mat;
ds.a.vol.dim=[3 2 1];
ds.a.vol.xform='scanner_anat';
function nii=get_expected_nii_pixdim()
nii=get_expected_nii_helper();
fields_to_clear={'quatern_b','quatern_c','quatern_d',...
'qoffset_x','qoffset_y','qoffset_z',...
'srow_x','srow_y','srow_z'};
nii.hdr.hist=clear_fields(nii.hdr.hist,fields_to_clear);
function nii=get_expected_nii_sform_and_qform()
nii=get_expected_nii_helper();
nii.hdr.hist.sform_code = 1;
nii.hdr.hist.qform_code = 1;
function nii=get_expected_nii_sform()
nii=get_expected_nii_helper();
nii.hdr.hist.sform_code = 1;
fields_to_clear={'quatern_b','quatern_c','quatern_d',...
'qoffset_x','qoffset_y','qoffset_z'};
nii.hdr.hist=clear_fields(nii.hdr.hist,fields_to_clear);
function nii=get_expected_nii_qform()
nii=get_expected_nii_helper();
nii.hdr.hist.qform_code = 1;
fields_to_clear={'srow_x','srow_y','srow_z'};
nii.hdr.hist=clear_fields(nii.hdr.hist,fields_to_clear);
function nii=get_expected_nii_helper()
hdr=struct();
hdr.dime.datatype = 16;
hdr.dime.dim = [ 4 3 2 1 2 1 1 1 ];
hdr.dime.pixdim = [ 0 2 2 2 0 0 0 0 ];
hdr.dime.intent_p1 = 0;
hdr.dime.intent_p2 = 0;
hdr.dime.intent_p3 = 0;
hdr.dime.intent_code = 0;
hdr.dime.slice_start = 0;
hdr.dime.slice_duration = 0;
hdr.dime.slice_end = 0;
hdr.dime.scl_slope = 0;
hdr.dime.scl_inter = 0;
hdr.dime.slice_code = 0;
hdr.dime.cal_max = 0;
hdr.dime.cal_min = 0;
hdr.dime.toffset = 0;
hdr.dime.xyzt_units = 10;
hdr.hk.sizeof_hdr = 348;
hdr.hk.data_type='';
hdr.hk.db_name='';
hdr.hk.extents = 0;
hdr.hk.session_error = 0;
hdr.hk.regular='r';
hdr.hk.dim_info = 0;
hdr.hist.descrip='';
hdr.hist.aux_file='';
hdr.hist.intent_name='';
hdr.hist.srow_x = [ 2 0 0 -1 ];
hdr.hist.srow_y = [ 0 2 0 -1 ];
hdr.hist.srow_z = [ 0 0 2 -1 ];
hdr.hist.quatern_c = 0;
hdr.hist.originator = [ 2 1 1 1 ];
hdr.hist.sform_code = 0;
hdr.hist.qform_code = 0;
% set up qform
m=[hdr.hist.srow_x;hdr.hist.srow_y;hdr.hist.srow_z];
quatern_a=.5*sqrt(1+m(1,1)+m(2,2)+m(3,3));
hdr.hist.quatern_b = .25*(m(3,2)-m(2,3)) / quatern_a;
hdr.hist.quatern_c = .25*(m(1,3)-m(3,1)) / quatern_a;
hdr.hist.quatern_d = .25*(m(2,1)-m(1,2)) / quatern_a;
hdr.hist.qoffset_x = m(1,4);
hdr.hist.qoffset_y = m(2,4);
hdr.hist.qoffset_z = m(3,4);
data=zeros(3,2,1,2);
data(:,:,1,1)=[ 2.0317 1.3494; -3.6849 -0.2617; -1.0504 -0.2040];
data(:,:,1,2)=[ 0.5838 -0.3973; 1.7235 2.3387; -1.3265 0.4823];
nii=struct();
nii.hdr=hdr;
nii.img=single(data);
function s=clear_fields(s,keys)
n=numel(keys);
for k=1:n
key=keys{k};
v=s.(key);
v(:)=0;
s.(key)=v;
end
function result=neuroelf_bless_wrapper(arg)
% deals with recent neuroelf (>v1.1), where bless is deprecated
s=warning('off','neuroelf:xff:deprecated');
resetter=onCleanup(@()warning(s));
result=bless(arg);