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