function [dim, index, attr_name, dim_name, values]=cosmo_dim_find(ds, dim_label, raise)
% find dimension attribute in dataset
%
% [dim, index, attr_name, dim_name]=cosmo_dim_find(ds, dim_label[, raise])
%
% Inputs:
% ds dataset struct
% dim_label dimension label
% raise if true, raise an error if the dimension is not found.
% Default: false
%
% Outputs:
% dim dimension where dim_label was found, 1=sample
% dimension, 2=feature dimension
% index position where dim_label was found, so that:
% ds.a.(dim_name).values{index}==dim_label
% attr_name 'sa' if dim==1, 'fa' if dim==2
% dim_name 'sdim' if dim==1, 'fdim' if dim==2
% values the values associated with the dimension
%
% Examples:
% % fMRI dataset, find first voxel dimension
% ds=cosmo_synthetic_dataset('type','fmri');
% [dim, index, attr_name, dim_name, values]=cosmo_dim_find(ds,'i');
% disp(dim)
% %|| 2
% disp(index)
% %|| 1
% disp(attr_name)
% %|| fa
% disp(dim_name)
% %|| fdim
% cosmo_disp(values)
% %|| [ 1 2 3 ]
%
% % MEEG time-frequency dataset, find 'time' dimension
% ds=cosmo_synthetic_dataset('type','timefreq','size','big');
% [dim, index, attr_name, dim_name, values]=cosmo_dim_find(ds,'time');
% disp(dim)
% %|| 2
% disp(index)
% %|| 3
% disp(attr_name)
% %|| fa
% disp(dim_name)
% %|| fdim
% cosmo_disp(values)
% %|| [ -0.2000 -0.1500 -0.1000 -0.0500 0 ]
% %
% % move 'time' from feature to sample dimension
% dst=cosmo_dim_transpose(ds,'time',1);
% [dim, index, attr_name, dim_name, values]=cosmo_dim_find(dst,'time');
% disp(dim)
% %|| 1
% disp(index)
% %|| 1
% disp(attr_name)
% %|| sa
% disp(dim_name)
% %|| sdim
% cosmo_disp(values)
% %|| [ -0.2000 ; -0.1500 ; -0.1000 ; -0.0500 ; 0 ]
%
% # For CoSMoMVPA's copyright information and license terms, #
% # see the COPYING file distributed with CoSMoMVPA. #
if nargin<3, raise=true; end
is_singleton=ischar(dim_label);
if is_singleton
dim_label={dim_label};
elseif ~iscellstr(dim_label)
error('Second input must be string or cell with strings');
end
nlabel=numel(dim_label);
dim=[];
index=zeros(nlabel,1);
values=cell(nlabel,1);
for k=1:nlabel
[d,i,an,dn,vs]=find_singleton(ds,dim_label{k},raise);
if k==1
dim=d;
attr_name=an;
dim_name=dn;
end
if isempty(d) || dim~=d || ~isequal(attr_name,an) || ...
~isequal(dim_name,dn)
dim=[];
break;
end
index(k)=i;
values{k}=vs;
end
if isempty(dim)
index=[];
attr_name=[];
dim_name=[];
values=[];
if raise
error('Unable to find all labels in the same dimension: %s',...
cosmo_strjoin(dim_label,', '));
end
else
if dim==1
index=index';
values=values';
end
if is_singleton
values=values{1};
end
end
function [dim, index, attr_name, dim_name, values]=find_singleton(ds,...
dim_label,raise)
infixes='sf';
for dim=1:numel(infixes)
infix=infixes(dim);
attr_name=[infix 'a'];
dim_name=[infix 'dim'];
if cosmo_isfield(ds, ['a.' dim_name '.labels'])
labels=ds.a.(dim_name).labels;
m=cosmo_match(labels, dim_label);
if any(m)
index=find(m);
if numel(index)>1 && raise
error('Duplicate label %s in .a.%s.labels', ...
dim_label, dim_name);
elseif ~cosmo_isfield(ds, ['a.' dim_name '.values'],...
raise)
% not all fields present
else
values=ds.a.(dim_name).values{index};
return
end
end
end
end
dim=[];
index=[];
attr_name=[];
dim_name=[];
values=[];
if raise
error('Not found: dimension label %s', dim_label);
end