Skip to content

Commit

Permalink
ENH - first attempt at adjusting ft_datatype_raw
Browse files Browse the repository at this point in the history
  • Loading branch information
schoffelen committed Apr 16, 2024
1 parent 1a39916 commit edc9b40
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 21 deletions.
3 changes: 2 additions & 1 deletion utilities/ft_checkdata.m
Expand Up @@ -135,6 +135,7 @@
parcellationstyle = ft_getopt(varargin, 'parcellationstyle'); % this will be passed on to the corresponding ft_datatype_xxx function
trialinfostyle = ft_getopt(varargin, 'trialinfostyle');
fsample = ft_getopt(varargin, 'fsample');
allowemptytrials = ft_getopt(varargin, 'allowemptytrials'); % this will be passed on to the corresponding ft_datatype_raw function

% determine the type of input data
israw = ft_datatype(data, 'raw');
Expand Down Expand Up @@ -276,7 +277,7 @@
if iscomp % this should go before israw/istimelock/isfreq
data = ft_datatype_comp(data, 'hassampleinfo', hassampleinfo);
elseif israw
data = ft_datatype_raw(data, 'hassampleinfo', hassampleinfo);
data = ft_datatype_raw(data, 'hassampleinfo', hassampleinfo, 'allowemptytrials', allowemptytrials);
elseif istimelock
data = ft_datatype_timelock(data, 'hassampleinfo', hassampleinfo);
elseif isfreq
Expand Down
77 changes: 76 additions & 1 deletion utilities/ft_datatype_raw.m
Expand Up @@ -75,6 +75,7 @@
version = ft_getopt(varargin, 'version', 'latest');
hassampleinfo = ft_getopt(varargin, 'hassampleinfo', 'ifmakessense'); % can be yes/no/ifmakessense
hastrialinfo = ft_getopt(varargin, 'hastrialinfo', 'ifmakessense'); % can be yes/no/ifmakessense
allowemptytrials = ft_getopt(varargin, 'allowemptytrials', 'yes');

% do some sanity checks
assert(isfield(data, 'trial') && isfield(data, 'time') && isfield(data, 'label'), 'inconsistent raw data structure, some field is missing');
Expand All @@ -96,16 +97,90 @@
else
hastrialinfo = istrue(hastrialinfo);
end
allowemptytrials = istrue(allowemptytrials);

if strcmp(version, 'latest')
version = '2011';
version = '2024';
end

if isempty(data)
return;
end

switch version
case '2024'
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if ~allowemptytrials
remove = false(numel(data.time),1);
for i=1:numel(data.time)
if isempty(data.time{i})
remove(i) = true;
end
end
data.time = data.time(~remove);
data.trial = data.trial(~remove);
if isfield(data, 'sampleinfo')
data.sampleinfo = data.sampleinfo(~remove,:);
end
if isfield(data, 'trialinfo')
data.trialinfo = data.trialinfo(~remove,:);
end
end

% ensure that the sensor structures are up to date
if isfield(data, 'grad')
data.grad = ft_datatype_sens(data.grad);
end
if isfield(data, 'elec')
data.elec = ft_datatype_sens(data.elec);
end
if isfield(data, 'opto')
data.opto = ft_datatype_sens(data.opto);
end

if ~isfield(data, 'fsample')
for i=1:length(data.time)
if length(data.time{i})>1
data.fsample = 1/mean(diff(data.time{i}));
break
else
data.fsample = nan;
end
end
if isnan(data.fsample)
ft_warning('cannot determine sampling frequency');
end
end

if isfield(data, 'offset')
data = rmfield(data, 'offset');
end

% the trialdef field should be renamed into sampleinfo
if isfield(data, 'trialdef')
data.sampleinfo = data.trialdef;
data = rmfield(data, 'trialdef');
end

if (hassampleinfo && ~isfield(data, 'sampleinfo')) || (hastrialinfo && ~isfield(data, 'trialinfo'))
% try to reconstruct the sampleinfo and trialinfo
data = fixsampleinfo(data);
end

if ~hassampleinfo && isfield(data, 'sampleinfo')
data = rmfield(data, 'sampleinfo');
end

if ~hastrialinfo && isfield(data, 'trialinfo')
data = rmfield(data, 'trialinfo');
end

if isfield(data, 'sampleinfo') && istable(data.sampleinfo)
% the sampleinfo contains two columns with the begsample and endsample and can always be represented as a numeric array
% the trialinfo can be either a numeric array or a table
data.sampleinfo = table2array(data.sampleinfo);
end

case '2011'
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% ensure that the sensor structures are up to date
Expand Down
18 changes: 0 additions & 18 deletions utilities/ft_selectdata.m
Expand Up @@ -449,24 +449,6 @@
end
end

% remove the empty trials from a raw/comp data structure
if strcmp(dtype, 'raw') || strcmp(dtype, 'comp')
for i=1:length(varargin)
trialnotempty = true(length(varargin{i}.trial),1);
for j=1:length(varargin{i}.trial)
trialnotempty(j) = ~isempty(varargin{i}.trial{j});
end
varargin{i}.trial = varargin{i}.trial(trialnotempty);
varargin{i}.time = varargin{i}.time(trialnotempty);
if isfield(varargin{i}, 'trialinfo')
varargin{i}.trialinfo = varargin{i}.trialinfo(trialnotempty,:);
end
if isfield(varargin{i}, 'sampleinfo')
varargin{i}.sampleinfo = varargin{i}.sampleinfo(trialnotempty,:);
end
end
end

% restore the source.avg field, this keeps the output reasonably consistent with the
% old-style source representation of the input
if strcmp(dtype, 'source') && ~isempty(restoreavg)
Expand Down
6 changes: 5 additions & 1 deletion utilities/private/time2offset.m
Expand Up @@ -35,4 +35,8 @@
%
% $Id$

offset = round(time(1)*fsample);
if ~isempty(time)
offset = round(time(1)*fsample);
else
offset = nan;
end

0 comments on commit edc9b40

Please sign in to comment.