Skip to content

Commit

Permalink
Merge pull request fieldtrip#2413 from schoffelen/gdf
Browse files Browse the repository at this point in the history
gdf event reading
  • Loading branch information
robertoostenveld authored May 14, 2024
2 parents 27a4918 + 4274be6 commit 042abcf
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 8 deletions.
36 changes: 28 additions & 8 deletions fileio/ft_read_event.m
Original file line number Diff line number Diff line change
Expand Up @@ -492,15 +492,35 @@
hdr = ft_read_header(filename);
end
% the following applies to Biosemi data that is stored in the gdf format
statusindx = find(strcmp(hdr.label, 'STATUS'));
if length(statusindx)==1
% represent the rising flanks in the STATUS channel as events
event = read_trigger(filename, 'header', hdr, 'dataformat', dataformat, 'begsample', flt_minsample, 'endsample', flt_maxsample, 'chanindx', statusindx, 'detectflank', 'up', 'trigshift', trigshift, 'trigpadding', trigpadding, 'fixbiosemi', true);
else
ft_warning('BIOSIG does not have a consistent event representation, skipping events')
event = [];
if ~isempty(chanindx)
chanindx = find(strcmp(hdr.label, 'STATUS'));
end

event = [];
if length(chanindx)==1
% represent the rising flanks in the STATUS (or user specified) channel as events
event = read_trigger(filename, 'header', hdr, 'dataformat', dataformat, 'begsample', flt_minsample, 'endsample', flt_maxsample, 'chanindx', chanindx, 'detectflank', detectflank, 'trigshift', trigshift, 'trigpadding', trigpadding, 'fixbiosemi', true);
else
ft_warning('data does not have a STATUS channel');
end

% make an attempt to get the events from the BIOSIG hdr
if isfield(hdr.orig, 'EVENT')
% this is code that has been inspired by eeglab's biosig2eeglabevent
event_hdr = biosig2fieldtripevent(hdr.orig.EVENT);
else
event_hdr = [];
end

if ~isempty(event) && ~isempty(event_hdr)
% merge the two structs
event = appendstruct(event(:), event_hdr(:));
smp = [event.sample];
[srt, indx] = sort(smp);
event = event(indx);
elseif isempty(event) && ~isempty(event_hdr)
event = event_hdr(:);
end

case 'AnyWave'
event = read_ah5_markers(hdr, filename);

Expand Down
79 changes: 79 additions & 0 deletions fileio/private/biosig2fieldtripevent.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
function eventout = biosig2fieldtripevent(eventin)

% BIOSIG2FIELDTRIPEVENT converts event information from a biosig hdr into
% fieldtrip events

ft_hastoolbox('BIOSIG', 1);
f = which('sopen.m');
[p,f,e] = fileparts(f);

if contains(p, 'external')
% assume the biosig to be shipped with the fieldtrip distro, in which
% case we need to look into fullfile(p,'doc')
else
% assume the biosig to be from the official distro, in which case we need
% to look into ../doc, relative to p
tok = tokenize(p, filesep);
p = fullfile(tok{1:end-1});
end

try
EVT = sopen(fullfile(p, 'doc', 'eventcodes.txt'));sclose(EVT);
catch
warning('failed to load eventcodes');
eventout = [];
return;
end

eventout = struct([]);
if isfield(eventin, 'TYP')
for index = 1:length( eventin.TYP )
eType = eventin.TYP(index);

% use file in
% https://sccn.ucsd.edu/bugzilla/show_bug.cgi?id=1387 to test
% for boundary events
if eType < 256 && isfield(eventin,'CodeDesc') && eType < length(eventin.CodeDesc)
eventout(index).type = eventin.CodeDesc{eType};
eventout(index).value = eType;
elseif isfield(EVT, 'EVENT') && isfield(EVT.EVENT,'CodeIndex') && isfield(EVT.EVENT,'CodeDesc')
if any(EVT.EVENT.CodeIndex==eType)
eventout(index).type = EVT.EVENT.CodeDesc{EVT.EVENT.CodeIndex==eType};
else
eventout(index).type = 'event';
end
eventout(index).value = eType;

% FIXME I leave the below in for reference, I don't know what it
% means, but we might need it in the future
% if eType == 32766 || eType == 32767
% eventout(index).edfplustype = eventout(index).type;
% eventout(index).type = eeg_boundarytype(event);
% end
else
eventout(index).type = 'event';
eventout(index).value = eType;
end
end
end
if isfield(eventin, 'POS')
for index = 1:length( eventin.POS )
eventout(index).sample = eventin.POS(index);
end
end
if isfield(eventin, 'DUR')
if any( [ eventin.DUR ] )
for index = 1:length( eventin.DUR )
eventout(index).duration = eventin.DUR(index);
end
end
end
if isfield(eventin, 'CHN')
if any( [ eventin.CHN ] )
for index = 1:length( eventin.CHN )
eventout(index).chanindex = eventin.CHN(index);
end
end
end

eventout = eventout(:);
16 changes: 16 additions & 0 deletions test/test_pull2413.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
function test_pull2413

% MEM 1gb
% WALLTIME 00:10:00
% DEPENDENCY ft_read_event
% DATA private

%%

datadir = dccnpath('/home/common/matlab/fieldtrip/data/test/original/eeg/gdf/');

d = dir(fullfile(datadir, '*.gdf'));
for k = 1:numel(d)
event = ft_read_event(fullfile(d(k).folder, d(k).name));
end

0 comments on commit 042abcf

Please sign in to comment.