1 %
openbdf() - Opens an BDF File (European Data Format
for Biosignals) in MATLAB (R)
4 % >> EDF=openedf(FILENAME)
6 % Note: About EDF -> www.biosemi.com/faq/file_format.htm
8 % Author: Alois Schloegl, 5.Nov.1998
12 % Copyright (C) 1997-1998 by Alois Schloegl
14 % Ver 2.20 18.Aug.1998
15 % Ver 2.21 10.Oct.1998
18 % For use under Octave define the following
function
19 %
function s=upper(s); s=toupper(s); end;
21 % V2.12 Warning
for missing Header information
22 % V2.20 EDF.AS.* changed
23 % V2.30 EDF.T0 made Y2K compatible until Year 2090
25 % This program is free software; you can redistribute it and/or
26 % modify it under the terms of the GNU General Public License
27 % as published by the Free Software Foundation; either version 2
28 % of the License, or (at your option) any later version.
30 % This program is distributed in the hope that it will be useful,
31 % but WITHOUT ANY WARRANTY; without even the implied warranty of
32 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 % GNU General Public License
for more details.
35 % You should have received a copy of the GNU General Public License
36 % along with
this program;
if not, write to the Free Software
37 % Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
39 % Name changed
for bdf files Sept 6,2002 T.S. Lorig
40 % Header updated
for EEGLAB format (update web link too) - Arnaud Delorme 14 Oct 2002
42 function [DAT,H1]=
openbdf(FILENAME)
44 SLASH=
'/'; % defines Seperator
for Subdirectories
48 if cname(1:2)==
'PC' SLASH=BSLASH; end;
50 fid=fopen(FILENAME,
'r',
'ieee-le');
52 fprintf(2,[
'Error LOADEDF: File ' FILENAME
' not found\n']);
58 EDF.FileName = FILENAME;
60 PPos=min([max(find(FILENAME==
'.')) length(FILENAME)+1]);
61 SPos=max([0 find((FILENAME==
'/') | (FILENAME==BSLASH))]);
62 EDF.FILE.Ext = FILENAME(PPos+1:length(FILENAME));
63 EDF.FILE.Name = FILENAME(SPos+1:PPos-1);
67 EDF.FILE.Path = FILENAME(1:SPos-1);
69 EDF.FileName = [EDF.FILE.Path SLASH EDF.FILE.Name
'.' EDF.FILE.Ext];
71 H1=setstr(fread(EDF.FILE.FID,256,
'char')
'); %
72 EDF.VERSION=H1(1:8); % 8 Byte Versionsnummer
73 %if 0 fprintf(2,'LOADEDF: WARNING Version EDF Format %i
',ver); end;
74 EDF.PID = deblank(H1(9:88)); % 80 Byte local patient identification
75 EDF.RID = deblank(H1(89:168)); % 80 Byte local recording identification
76 %EDF.H.StartDate = H1(169:176); % 8 Byte
77 %EDF.H.StartTime = H1(177:184); % 8 Byte
78 EDF.T0=[str2num(H1(168+[7 8])) str2num(H1(168+[4 5])) str2num(H1(168+[1 2])) str2num(H1(168+[9 10])) str2num(H1(168+[12 13])) str2num(H1(168+[15 16])) ];
80 % Y2K compatibility until year 2090
81 if EDF.VERSION(1)=='0
'
83 EDF.T0(1)=2000+EDF.T0(1);
85 EDF.T0(1)=1900+EDF.T0(1);
88 % in a future version, this is hopefully not needed
91 EDF.HeadLen = str2num(H1(185:192)); % 8 Byte Length of Header
92 % reserved = H1(193:236); % 44 Byte
93 EDF.NRec = str2num(H1(237:244)); % 8 Byte # of data records
94 EDF.Dur = str2num(H1(245:252)); % 8 Byte # duration of data record in sec
95 EDF.NS = str2num(H1(253:256)); % 8 Byte # of signals
97 EDF.Label = setstr(fread(EDF.FILE.FID,[16,EDF.NS],'char')');
98 EDF.Transducer = setstr(fread(EDF.FILE.FID,[80,EDF.NS],
'char')
');
99 EDF.PhysDim = setstr(fread(EDF.FILE.FID,[8,EDF.NS],'char')');
101 EDF.PhysMin= str2num(setstr(fread(EDF.FILE.FID,[8,EDF.NS],
'char')
'));
102 EDF.PhysMax= str2num(setstr(fread(EDF.FILE.FID,[8,EDF.NS],'char')'));
103 EDF.DigMin = str2num(setstr(fread(EDF.FILE.FID,[8,EDF.NS],
'char')
')); %
104 EDF.DigMax = str2num(setstr(fread(EDF.FILE.FID,[8,EDF.NS],'char')')); %
106 % check validity of DigMin and DigMax
107 if (length(EDF.DigMin) ~= EDF.NS)
108 fprintf(2,
'Warning OPENEDF: Failing Digital Minimum\n');
109 EDF.DigMin = -(2^15)*ones(EDF.NS,1);
111 if (length(EDF.DigMax) ~= EDF.NS)
112 fprintf(2,
'Warning OPENEDF: Failing Digital Maximum\n');
113 EDF.DigMax = (2^15-1)*ones(EDF.NS,1);
115 if (any(EDF.DigMin >= EDF.DigMax))
116 fprintf(2,
'Warning OPENEDF: Digital Minimum larger than Maximum\n');
118 % check validity of PhysMin and PhysMax
119 if (length(EDF.PhysMin) ~= EDF.NS)
120 fprintf(2,
'Warning OPENEDF: Failing Physical Minimum\n');
121 EDF.PhysMin = EDF.DigMin;
123 if (length(EDF.PhysMax) ~= EDF.NS)
124 fprintf(2,
'Warning OPENEDF: Failing Physical Maximum\n');
125 EDF.PhysMax = EDF.DigMax;
127 if (any(EDF.PhysMin >= EDF.PhysMax))
128 fprintf(2,
'Warning OPENEDF: Physical Minimum larger than Maximum\n');
129 EDF.PhysMin = EDF.DigMin;
130 EDF.PhysMax = EDF.DigMax;
132 EDF.PreFilt= setstr(fread(EDF.FILE.FID,[80,EDF.NS],
'char')
'); %
133 tmp = fread(EDF.FILE.FID,[8,EDF.NS],'char')'; % samples per data record
134 EDF.SPR = str2num(setstr(tmp)); % samples per data record
136 fseek(EDF.FILE.FID,32*EDF.NS,0);
138 EDF.Cal = (EDF.PhysMax-EDF.PhysMin)./ ...
139 (EDF.DigMax-EDF.DigMin);
140 EDF.Off = EDF.PhysMin - EDF.Cal .* EDF.DigMin;
141 tmp = find(EDF.Cal < 0);
142 EDF.Cal(tmp) = ones(size(tmp));
143 EDF.Off(tmp) = zeros(size(tmp));
145 EDF.Calib=[EDF.Off
';(diag(EDF.Cal))];
146 %EDF.Calib=sparse(diag([1; EDF.Cal]));
147 %EDF.Calib(1,2:EDF.NS+1)=EDF.Off';
149 EDF.SampleRate = EDF.SPR / EDF.Dur;
151 EDF.FILE.POS = ftell(EDF.FILE.FID);
152 if EDF.NRec == -1 % unknown record size, determine correct NRec
153 fseek(EDF.FILE.FID, 0,
'eof');
154 endpos = ftell(EDF.FILE.FID);
155 EDF.NRec = floor((endpos - EDF.FILE.POS) / (sum(EDF.SPR) * 2));
156 fseek(EDF.FILE.FID, EDF.FILE.POS,
'bof');
157 H1(237:244)=sprintf(
'%-8i',EDF.NRec); % write number of records
160 EDF.Chan_Select=(EDF.SPR==max(EDF.SPR));
162 if EDF.Chan_Select(k)
167 if findstr(upper(EDF.Label(k,:)),
'ECG')
169 elseif findstr(upper(EDF.Label(k,:)),'EKG')
171 elseif findstr(upper(EDF.Label(k,:)),'EEG')
173 elseif findstr(upper(EDF.Label(k,:)),'EOG')
175 elseif findstr(upper(EDF.Label(k,:)),'EMG')
180 EDF.AS.spb = sum(EDF.SPR); % Samples per Block
181 bi=[0;cumsum(EDF.SPR)];
185 idx2=[idx2, (k-1)*max(EDF.SPR)+(1:EDF.SPR(k))];
188 idx3=zeros(EDF.NS*maxspr,1);
189 for k=1:EDF.NS, idx3(maxspr*(k-1)+(1:maxspr))=bi(k)+ceil((1:maxspr)'/maxspr*EDF.SPR(k));end;
199 %DAT.MX=feval('loadxcm',EDF);