function is_ok=cosmo_check_dataset(ds, ds_type, error_if_not_ok)
% Check consistency of a dataset.
%
%
% is_ok=cosmo_dataset_check(ds, [ds_type,][,error_if_not_ok])
%
% Inputs:
% ds dataset struct.
% ds_type string indicating the specific type of dataset.
% Currently supports 'fmri' and 'meeg'.
% error_if_not_ok if true (the default) or a string, an error is
% raised if the dataset is not kosher (see below).
% If a string, then it is prefixed in the error
% message. If false, then no error is raised.
%
% Returns:
% is_ok boolean indicating kosherness of ds.
% It is consider ok if:
% - it has a field .samples with a PxQ array.
% - if it has a field .features [.samples], then
% it should be a struct, and each field in it
% should have P [Q] elements along the first
% [second] dimension or be empty.
% - .sa.{targets,chunks} are numeric vectors with
% integers (if present)
% - if ds_type is provided, then some more tests
% (depending on ds_type) are performed.
%
% Examples:
% cosmo_check_dataset([])
% %|| error('dataset not a struct')
%
% cosmo_check_dataset(struct())
% %|| error('dataset has no field .samples')
%
% % this (very minimal) dataset is kosher
% cosmo_check_dataset(struct('samples',zeros(2)))
% %|| true
%
% % error can be silenced
% cosmo_check_dataset('this is not ok',false)
% %|| false
%
% % run some more tests
% ds=cosmo_synthetic_dataset('type','fmri');
% cosmo_check_dataset(ds)
% %|| true
% ds.sa.chunks=[2;3]; % wrong size
% cosmo_check_dataset(ds)
% %|| error('sa.chunks has 2 values in dimension 1, expected 6')
% ds.sa.chunks={'a','b','c','a','b','c'}';
% cosmo_check_dataset(ds)
% %|| error('.sa.chunks must be numeric vector with integers')
%
% % set illegal dimension values
% ds=cosmo_synthetic_dataset('type','fmri');
% ds.a.fdim.values{1}=[1 2];
% cosmo_check_dataset(ds)
% %|| error('.fa.i must be vector with integers in range 1..2')
%
% % check for specific type of dataset
% ds=cosmo_synthetic_dataset('type','fmri');
% cosmo_check_dataset(ds,'meeg')
% %|| error('missing field .a.meeg for meeg-dataset');
%
% % destroy crucial information in fmri dataset
% % this error is only caught if explicit checking for fmri dataset is
% % enabled, because the dataset remains valid when considered as a
% % non-fmri dataset
% ds=cosmo_synthetic_dataset('type','fmri');
% % destroy volume information
% ds.a=rmfield(ds.a,'vol');
% cosmo_check_dataset(ds)
% %|| true % error not caught
% cosmo_check_dataset(ds,'fmri')
% %|| error('missing field .a.vol for fmri-dataset')
%
% % check meeg dataset
% ds=cosmo_synthetic_dataset('type','meeg');
% cosmo_check_dataset(ds,'meeg')
% %|| true
% ds.fa.chan=ds.fa.chan+6; % outside range
% cosmo_check_dataset(ds)
% %|| error('.fa.chan must be vector with integers in range 1..3')
%
% Notes:
% - if the second argument is a boolean then its value is used for
% error_if_not_ok, and ds_type is not used
% - this function throws one error at most, even if it is inconsistent for
% several reasons.
% - it is good practice to use this function when a new dataset is created
% to ensure consistency of the data
%
% # For CoSMoMVPA's copyright information and license terms, #
% # see the COPYING file distributed with CoSMoMVPA. #