cosmo dim remove skl

function [ds, attr, values] = cosmo_dim_remove(ds, dim_labels)
    % remove a dataset dimension
    %
    % [ds_result,attr,values]=cosmo_dim_remove(ds,dim_labels)
    %
    % Inputs:
    %   ds                  dataset struct
    %   dim_labels          cellstring with label(s) to remove. A single
    %                       string s is interpreted as s{1}
    %
    % Output:
    %   ds_result           dataset struct with dim_labels removed from
    %                       .a.{fdim,sdim} and .{fa,sa}.
    %   attr                struct based on .{fa,sa} but only with the fields in
    %                       dim_labels
    %   values              Nx1 cell based on .a.{fdim,sdim}.values, but only
    %                       with the fields in dim_labels. If dim_labels is a
    %                       string, then the output is values{1}.
    %
    % Example:
    %     % generate tiny fmri dataset
    %     ds=cosmo_synthetic_dataset();
    %     cosmo_disp(ds.a.fdim);
    %     %|| .labels
    %     %||   { 'i'  'j'  'k' }
    %     %|| .values
    %     %||   { [ 1         2         3 ]  [ 1         2 ]  [ 1 ] }
    %     cosmo_disp(ds.fa);
    %     %|| .i
    %     %||   [ 1         2         3         1         2         3 ]
    %     %|| .j
    %     %||   [ 1         1         1         2         2         2 ]
    %     %|| .k
    %     %||   [ 1         1         1         1         1         1 ]
    %     % remove 'j' and 'k' dimension label; only 'i' is left
    %     [ds_without_jk,attr,values]=cosmo_dim_remove(ds,{'j','k'});
    %     cosmo_disp(ds_without_jk.a.fdim);
    %     %|| .labels
    %     %||   { 'i' }
    %     %|| .values
    %     %||   { [ 1         2         3 ] }
    %     cosmo_disp(ds_without_jk.fa);
    %     %|| .i
    %     %||   [ 1         2         3         1         2         3 ]
    %     cosmo_disp(attr)
    %     %|| .j
    %     %||   [ 1         1         1         2         2         2 ]
    %     %|| .k
    %     %||   [ 1         1         1         1         1         1 ]
    %     cosmo_disp(values)
    %     %|| { [ 1         2 ]  [ 1 ] }
    %
    % See also: cosmo_dim_transpose
    %
    % #   For CoSMoMVPA's copyright information and license terms,   #
    % #   see the COPYING file distributed with CoSMoMVPA.           #

    has_char_label = ischar(dim_labels);
    if has_char_label
        dim_labels = {dim_labels};
    end
    nlabels = numel(dim_labels);

    [dim, remove_idxs, attr_name, dim_name] = cosmo_dim_find(ds, dim_labels);

    % update .fa / .sa
    xa = ds.(attr_name);

    attr = struct();
    for k = 1:nlabels
        label = dim_labels{k};
        if isfield(xa, label)
            attr.(label) = xa.(label);
            ds.(attr_name) = rmfield(ds.(attr_name), label);
        end
    end

    % update .a.fdim / .a.sdim
    xdim = ds.a.(dim_name);
    xdim_values = xdim.values;
    keep_msk = true(size(xdim_values));
    keep_msk(remove_idxs) = false;
    xdim.labels = xdim.labels(keep_msk);
    xdim.values = xdim.values(keep_msk);

    % remove from the input
    if any(keep_msk)
        % there are dimensions left
        ds.a.(dim_name) = xdim;
    else
        % no dimensions left, remove sdim or fdim
        ds.a = rmfield(ds.a, dim_name);
    end

    % set values to return
    values = xdim_values(remove_idxs);

    sz = size(values);
    assert(any(sz == 1));

    needs_transpose = sz(dim) ~= 1;
    if needs_transpose
        values = values';
    end

    if has_char_label
        % return singleton element
        assert(numel(values) == 1);
        values = values{1};
    end