Home > eeg > utils > read_bdf_marker_chans.m

read_bdf_marker_chans

PURPOSE ^

Reads events from Status channel in BDF file header and returns an EEGLAB

SYNOPSIS ^

function [event_st, HDR] = read_bdf_marker_chans(bdfFileName)

DESCRIPTION ^

 Reads events from Status channel in BDF file header and returns an EEGLAB
 type event structure and biosig-type HDR structure. Note, the HDR
 structure is incomplete because only parts of sopen were used. Thus, one
 should really only consult HDR.EVENT

 [event_st, HDR] = read_bdf_marker_chans(bdfFileName);

 Much of the code borrowed from biosig toolbox sopen() and
 bdf2biosig_events() functions.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [event_st, HDR] = read_bdf_marker_chans(bdfFileName)
0002 % Reads events from Status channel in BDF file header and returns an EEGLAB
0003 % type event structure and biosig-type HDR structure. Note, the HDR
0004 % structure is incomplete because only parts of sopen were used. Thus, one
0005 % should really only consult HDR.EVENT
0006 %
0007 % [event_st, HDR] = read_bdf_marker_chans(bdfFileName);
0008 %
0009 % Much of the code borrowed from biosig toolbox sopen() and
0010 % bdf2biosig_events() functions.
0011 
0012 % 04Jul2012 Petr Janata
0013 
0014 if ~exist(bdfFileName,'file')
0015     error('Could not locate file: %s', bdfFileName)
0016 end
0017 
0018 %%%%% Define Valid Data types %%%%%%
0019 %GDFTYPES=[0 1 2 3 4 5 6 7 16 17 255+(1:64) 511+(1:64)];
0020 GDFTYPES=[0 1 2 3 4 5 6 7 16 17 18 255+[1 12 22 24] 511+[1 12 22 24]];
0021 
0022 %%%%% Define Size for each data type %%%%%
0023 GDFTYP_BYTE=zeros(1,512+64);
0024 GDFTYP_BYTE(256+(1:64))=(1:64)/8;
0025 GDFTYP_BYTE(512+(1:64))=(1:64)/8;
0026 GDFTYP_BYTE(1:19)=[1 1 1 2 2 4 4 8 8 4 8 0 0 0 0 0 4 8 16]';
0027 
0028 HDR.FileName = bdfFileName;
0029 HDR.FILE.stdout = 1;
0030 HDR.FILE.stderr = 2;
0031 HDR.FILE.PERMISSION='r';
0032 
0033 % Read in Header information
0034 HDR = getfiletype(HDR);
0035 [HDR.FILE.FID]=fopen(HDR.FileName,[HDR.FILE.PERMISSION,'b'],'ieee-le');
0036                 
0037 
0038 %%% Read Fixed Header %%%
0039 [H1,count]=fread(HDR.FILE.FID,[1,192],'uint8');     %
0040 if count<192,
0041     HDR.ErrNo = [64,HDR.ErrNo];
0042     return;
0043 end;
0044 H1(193:256)= fread(HDR.FILE.FID,[1,256-192],'uint8');     %
0045 H1 = char(H1);
0046 
0047 H2idx = [16 80 8 8 8 8 8 80 8 32];
0048 
0049 HDR.VERSION=char(H1(1:8));                     % 8 Byte  Versionsnummer
0050 if all(abs(H1(1:8))==[255,abs('BIOSEMI')]),
0051     HDR.VERSION = -1;
0052 end
0053 
0054 HDR.HeadLen = str2double(H1(185:192));           % 8 Bytes  Length of Header
0055 HDR.reserved1=H1(193:236);              % 44 Bytes reserved
0056 HDR.NRec    = str2double(H1(237:244));     % 8 Bytes  # of data records
0057 HDR.Dur     = str2double(H1(245:252));     % 8 Bytes  # duration of data record in sec
0058 HDR.NS      = str2double(H1(253:256));     % 4 Bytes  # of signals
0059 HDR.AS.H1 = H1;                         % for debugging the EDF Header
0060 
0061 idx1=cumsum([0 H2idx]);
0062 idx2=HDR.NS*idx1;
0063 
0064 h2=zeros(HDR.NS,256);
0065 [H2,count]=fread(HDR.FILE.FID,HDR.NS*256,'uint8');
0066 if count < HDR.NS*256
0067     HDR.ErrNo=[8,HDR.ErrNo];
0068     return;
0069 end;
0070 
0071 %tmp=find((H2<32) | (H2>126)); % would confirm
0072 tmp = find((H2<32) | ((H2>126) & (H2~=255) & (H2~=181)& (H2~=230)));
0073 if ~isempty(tmp) %%%%% not EDF because filled out with ASCII(0) - should be spaces
0074     H2(tmp) = 32;
0075     HDR.ErrNo = [1026,HDR.ErrNo];
0076 end;
0077 
0078 for k=1:length(H2idx);
0079     %disp([k size(H2) idx2(k) idx2(k+1) H2idx(k)]);
0080     h2(:,idx1(k)+1:idx1(k+1))=reshape(H2(idx2(k)+1:idx2(k+1)),H2idx(k),HDR.NS)';
0081 end;
0082 
0083 h2=char(h2);
0084 
0085 HDR.Label      =            h2(:,idx1(1)+1:idx1(2));
0086 HDR.Transducer =    cellstr(h2(:,idx1(2)+1:idx1(3)));
0087 HDR.PhysDim    =            h2(:,idx1(3)+1:idx1(4));
0088 HDR.PhysMin    = str2double(h2(:,idx1(4)+1:idx1(5)))';
0089 HDR.PhysMax    = str2double(h2(:,idx1(5)+1:idx1(6)))';
0090 HDR.DigMin     = str2double(h2(:,idx1(6)+1:idx1(7)))';
0091 HDR.DigMax     = str2double(h2(:,idx1(7)+1:idx1(8)))';
0092 HDR.PreFilt    =            h2(:,idx1(8)+1:idx1(9));
0093 HDR.AS.SPR     = str2double(h2(:,idx1(9)+1:idx1(10)));
0094 
0095 if (HDR.VERSION ~= -1),
0096     HDR.GDFTYP     = 3*ones(1,HDR.NS);    %    datatype
0097 else
0098     HDR.GDFTYP     = (255+24)*ones(1,HDR.NS);    %    datatype
0099 end;
0100 
0101 HDR.AS.spb = sum(HDR.AS.SPR);    % Samples per Block
0102 HDR.AS.bi  = [0;cumsum(HDR.AS.SPR(:))];
0103 HDR.AS.bpb = sum(ceil(HDR.AS.SPR.*GDFTYP_BYTE(HDR.GDFTYP+1)'));    % Bytes per Block
0104 
0105 HDR.EVENT.POS = [];
0106 HDR.EVENT.TYP = [];
0107 
0108 tmp = strmatch('Status',HDR.Label);
0109 HDR.BDF.Status.Channel = tmp;
0110 
0111 % Move to the beginning of the Status block
0112 status = fseek(HDR.FILE.FID,HDR.HeadLen+HDR.AS.bi(HDR.BDF.Status.Channel)*3,'bof');
0113 
0114 % Read in the Status information.  We are dealing with 24 bits per event,
0115 % so read in a groups of 3 unsigned 8 bit integers
0116 [t,c] = fread(HDR.FILE.FID,inf,[int2str(HDR.AS.SPR(HDR.BDF.Status.Channel)*3),'*uint8'],HDR.AS.bpb-HDR.AS.SPR(HDR.BDF.Status.Channel)*3);
0117 
0118 % Close the file
0119 fclose(HDR.FILE.FID);
0120 
0121 % Convert into 24 bit number
0122 HDR.BDF.ANNONS = reshape(double(t),3,length(t)/3)'*2.^[0;8;16];
0123 
0124 t = HDR.BDF.ANNONS; % these values are always high and go low when an event occurs
0125 eventVector = bitand(t, hex2dec('00ffff'));
0126 
0127 %% Only inspect bits 9-16
0128 % Because marker events are occuring on discrete lines the problem of
0129 % identifying event onsets is simplified because we only need to look at
0130 % state transitions on one line at a time
0131 bitOffset = 8;
0132 eventVector = bitshift(eventVector,-bitOffset);
0133 
0134 nbits = 8;
0135 for ibit = 1:nbits
0136     onsetMask = diff([0; ~bitget(eventVector,ibit)]) > 0;
0137     if any(onsetMask)
0138         fprintf('Found %d events on bit %d\n', sum(onsetMask), ibit+bitOffset);
0139         HDR.EVENT.POS = [HDR.EVENT.POS; find(onsetMask)];
0140         HDR.EVENT.TYP = [HDR.EVENT.TYP; repmat(2^(ibit+bitOffset-1),sum(onsetMask),1)];
0141     end
0142 end
0143 
0144 % Sort the events
0145 [HDR.EVENT.POS, idx] = sort(HDR.EVENT.POS, 'ascend');
0146 HDR.EVENT.TYP = HDR.EVENT.TYP(idx);
0147 
0148 % Create EEGLAB event structure
0149 event_st = struct('type',[],'latency',[],'duration',[]);
0150 for iev = 1:length(HDR.EVENT.POS)
0151     event_st(iev).type = HDR.EVENT.TYP(iev);
0152     event_st(iev).latency = HDR.EVENT.POS(iev);
0153 end
0154 return

Generated on Wed 20-Sep-2023 04:00:50 by m2html © 2003