1function [HDR]=mwfopen(HDR,PERMISSION,arg3,arg4,arg5,arg6)
2% MWFOPEN reads MFER files
3%
4% HDR = mwfopen(Filename,PERMISSION);
5%
6% HDR contains the Headerinformation and internal data
7%
8% see also: SOPEN, SREAD, SSEEK, STELL, SCLOSE, SWRITE, SEOF
9
10
11% This program is free software; you can redistribute it and/or
12% modify it under the terms of the GNU General Public License
13% as published by the Free Software Foundation; either version 3
14% of the License, or (at your option) any later version.
15
16%	(C) 2004,2007,2008,2013 by Alois Schloegl <alois.schloegl@gmail.com>
17% 	(C) 2013, Peter Beck, Joaneum Research
18%    	This is part of the BIOSIG-toolbox http://biosig.sf.net/
19
20
21if nargin<1, PERMISSION='rb'; end;
22
23if ischar(HDR)
24        tmp=HDR;
25        HDR=[];
26        HDR.FileName=tmp;
27end;
28
29VER = version;
30
31HDR.FILE.FID = fopen(HDR.FileName,PERMISSION,'ieee-be');
32HDR.Endianity= 'ieee-be';
33
34%%% Default values %%%
35HDR.SampleRate = 1000;
36HDR.GDFTYP = 3;
37HDR.AS.bps = 2;
38HDR.SPR = NaN;
39HDR.NS = 1;
40HDR.NRec = NaN;
41HDR.Off = 0;
42HDR.Cal = NaN;
43
44fprintf(2,'Warning MWFOPEN: support of MFER format not complete, but in testing state\n');
45%% default values
46% standard 12 leads ECG codes
47ECG12LeadsCodes(1:9)={'I';'II';'V1';'V2';'V3';'V4';'V5';'V6';'V1'};
48ECG12LeadsCodes(11:15)={'V3R';'V4R';'V5R';'V6R';'V7R'};
49ECG12LeadsCodes(61:64)={'III';'aVR';'aVL';'aVF'};
50ECG12LeadsCodes(66:69)={'V8';'V9';'V8R';'V9R'};
51
52if ~isempty(findstr(PERMISSION,'r')),		%%%%% READ
53        HDR.FILE.OPEN = 1;
54        HDR.FRAME.N = 0;
55        count = 1;
56        %while count>0, %~feof(HDR.FILE.FID)
57        tag = fread(HDR.FILE.FID,1,'uchar');
58        while ~feof(HDR.FILE.FID)
59                len = fread(HDR.FILE.FID,1,'uint8');
60                %fprintf(1,'[%i] Tag %i: (%i)\n',ftell(HDR.FILE.FID),tag,len);
61
62                if (len < 0) || (len > 127),
63                        l   = mod(len,128);
64                        len = fread(HDR.FILE.FID,[l,1],'uchar');
65                        %len = 256.^[0:l-1]*len;
66                        len = 256.^[l-1:-1:0]*len;
67                end;
68                % tmp = fread(HDR.FILE.FID,[1,len],'uint8');
69                % fprintf(1,'[%i] Tag %i: (%i)\n',ftell(HDR.FILE.FID),tag,len);
70
71                if 0,
72                        [tmp,count] = fread(HDR.FILE.FID,[1,len],'uint8');
73
74                elseif tag==0;
75                        [tmp,count] = fread(HDR.FILE.FID,[1,1],'uint8');
76
77                elseif tag==1;
78                        [tmp,count] = fread(HDR.FILE.FID,[1,1],'uint8');
79                        if 0,
80                        elseif (tmp==0) && strcmp(HDR.Endianity,'ieee-le'),
81                                tmp = ftell(HDR.FILE.FID);
82                                HDR.Endianity='ieee-be';
83                                fclose(HDR.FILE.FID);
84                                HDR.FILE.FID = fopen(HDR.FileName,PERMISSION,HDR.Endianity);
85                                fseek(HDR.FILE.FID,tmp,'bof');
86                        elseif (tmp==1) && strcmp(HDR.Endianity,'ieee-be'),
87                                tmp = ftell(HDR.FILE.FID);
88                                HDR.Endianity='ieee-le';
89                                fclose(HDR.FILE.FID);
90                                HDR.FILE.FID = fopen(HDR.FileName,PERMISSION,HDR.Endianity);
91                                fseek(HDR.FILE.FID,tmp,'bof');
92                        else
93                        end;
94
95                elseif tag==2;
96                        [tmp,count] = fread(HDR.FILE.FID,[1,len],'uint8');
97                        HDR.Version = tmp;
98
99                elseif tag==3;
100                        [tmp,count] = fread(HDR.FILE.FID,[1,len],'uint8');
101                        HDR.tag03 = tmp;
102
103                elseif tag==4;          % channel number
104                        if len == 0;
105                                tmp = NaN;
106                        elseif len == 1;
107                                [tmp,count] = fread(HDR.FILE.FID,1,'uint8');
108                        elseif len == 2;
109                                [tmp,count] = fread(HDR.FILE.FID,1,'int16');
110                        elseif len == 3;
111                                %[tmp,count] = fread(HDR.FILE.FID,1,'bit24');
112                                [tmp,count] = fread(HDR.FILE.FID,3,'uint8');
113                                tmp = (2.^[16,8,0])*tmp;
114                        elseif len == 4;
115                                [tmp,count] = fread(HDR.FILE.FID,1,'int32');
116                        else
117                                fprintf(2,'Error MWFOPEN: len=%i exceeds max length (4) in tag 04h\n',len);
118                        end;
119                        %[HDR.SPR,count] = fread(HDR.FILE.FID,[1,len],'uchar');
120                        HDR.SPR = tmp;
121
122                elseif tag==5;
123%                        [tmp,count] = fread(HDR.FILE.FID,[1,len],'uchar');
124                        if len == 0;
125                                tmp = 1;
126                        elseif len == 1;
127                                [tmp,count] = fread(HDR.FILE.FID,1,'int8');
128                        elseif len == 2;
129                                [tmp,count] = fread(HDR.FILE.FID,1,'int16');
130                        elseif len == 3;
131                                %[tmp,count] = fread(HDR.FILE.FID,1,'bit24');
132                                [tmp,count] = fread(HDR.FILE.FID,3,'uint8');
133                                tmp = (2.^[16,8,0])*tmp;
134                                %tmp = (2.^[0:8:16])*tmp;
135                        elseif len == 4;
136                                [tmp,count] = fread(HDR.FILE.FID,1,'int32');
137                        else
138                                fprintf(2,'Error MWFOPEN: max length exceeded in tag 05h\n');
139                        end;
140                        HDR.NS = tmp; %*256.^[len-1:-1:0]';
141
142                elseif tag==6;
143                        if     len==0; 	tmp = NaN;
144                        elseif len==1;	[tmp,count] = fread(HDR.FILE.FID,1,'int8');
145                        elseif len==2;	[tmp,count] = fread(HDR.FILE.FID,1,'int16');
146                        elseif len==3;
147                                % [tmp,count] = fread(HDR.FILE.FID,1,'bit24')
148                                [tmp,count] = fread(HDR.FILE.FID,3,'uint8');
149                                tmp = (2.^[16,8,0])*tmp;
150                        elseif len==4;	[tmp,count] = fread(HDR.FILE.FID,1,'int32');
151                        else   fprintf(2,'Error MWFOPEN: max length exceeded in tag 06h\n');
152                        end;
153                        HDR.NRec = tmp;
154
155                elseif tag==7;
156                        [tmp,count] = fread(HDR.FILE.FID,[1,len],'uchar');
157                        HDR.Pointer = tmp*256.^[0:len-1]';
158
159                elseif tag==8;
160                        [tmp,count] = fread(HDR.FILE.FID,[1,len],'uchar');
161                        if     tmp==0,	HDR.MFER.WaveFormType = 'undefined';
162                        elseif tmp==1,	HDR.MFER.WaveFormType = 'ECG_STD12';
163                        elseif tmp==2,	HDR.MFER.WaveFormType = 'ECG_LTERM';
164                        elseif tmp==3,	HDR.MFER.WaveFormType = 'Vectorcardiogram';
165                        elseif tmp==4,	HDR.MFER.WaveFormType = 'Stress_ECG';
166                        elseif tmp==5,	HDR.MFER.WaveFormType = 'ECG_LTERM';
167                        else		HDR.MFER.WaveFormType = tmp;
168			end
169
170                elseif tag==9;
171                        [tmp,count] = fread(HDR.FILE.FID,[1,len],'uchar');
172                        HDR.Label = char(tmp);
173
174                elseif tag==10;
175                        [tmp,count] = fread(HDR.FILE.FID,[1,len],'uchar');
176                        if tmp==0;	% int16, default
177                                HDR.GDFTYP = 3;
178                                HDR.AS.bps = 2;
179                        elseif tmp==1;	% uint16
180                                HDR.GDFTYP = 4;
181                                HDR.AS.bps = 2;
182                        elseif tmp==2;	% int32
183                                HDR.GDFTYP = 5;
184                                HDR.AS.bps = 4;
185                        elseif tmp==3;	% uint8
186                                HDR.GDFTYP = 2;
187                                HDR.AS.bps = 1;
188                        elseif tmp==4;	% 16bit status
189                                HDR.GDFTYP = 4;
190                                HDR.AS.bps = 2;
191                        elseif tmp==5;	% int8
192                                HDR.GDFTYP = 1;
193                                HDR.AS.bps = 1;
194                        elseif tmp==6;	% uint32
195                                HDR.GDFTYP = 6;
196                                HDR.AS.bps = 4;
197                        elseif tmp==7;	% float32
198                                HDR.GDFTYP = 16;
199                                HDR.AS.bps = 4;
200                        elseif tmp==8;	% float64
201                                HDR.GDFTYP = 17;
202                                HDR.AS.bps = 8;
203                        elseif tmp==9;	% 8 bit AHA compression
204                                HDR.GDFTYP = 4;
205                                HDR.AS.bps = NaN;
206                                fprintf(2,'Error MWFOPEN: compression not supported, yet.\n');
207                        end;
208
209                elseif tag==11;
210                        [tmp1,count] = fread(HDR.FILE.FID,2,'int8');
211                        len = len - 2;
212                        if     len == 1;	[tmp,count] = fread(HDR.FILE.FID,1,'int8');
213                        elseif len == 2;	[tmp,count] = fread(HDR.FILE.FID,1,'int16');
214                        elseif len == 3;
215                                % [tmp,count] = fread(HDR.FILE.FID,1,'bit24');
216                                [tmp,count] = fread(HDR.FILE.FID,3,'uint8');
217                                tmp = (2.^[16,8,0])*tmp;
218                        elseif len == 4;	[tmp,count] = fread(HDR.FILE.FID,1,'int32');
219                        end;
220                        e = 10^tmp1(2);
221                        if     tmp1(1)==0,
222                                HDR.Xphysdim = 'Hz';
223                                HDR.SampleRate=tmp*e;
224                        elseif tmp1(1)==1,
225                                HDR.Xphysdim = 's';
226                                HDR.SampleRate= 1/(tmp*e);
227                        elseif tmp1(1)==2,
228                                HDR.Xphysdim = 'm';
229                                HDR.SampleRate=tmp*e;
230                        end;
231
232                elseif tag==12;          % sensitivity, resolution, gain, calibration,
233                        [tmp,count] = fread(HDR.FILE.FID,2,'int8');
234                        if     tmp(1)== 0, HDR.PhysDimCode = 4256; %% V
235                        elseif tmp(1)== 1, HDR.PhysDimCode = 3872; %% mmHg
236                   	elseif tmp(1)== 2, HDR.PhysDimCode = 3840; %% Pa
237                        elseif tmp(1)== 3, HDR.PhysDimCode = 3904; %% cmH2O
238                        elseif tmp(1)== 4, HDR.PhysDim     = 'mmHg/S';
239                        elseif tmp(1)== 5, HDR.PhysDimCode = 3808; %% dyne
240                        elseif tmp(1)== 6, HDR.PhysDimCode = 3776; %% N
241                        elseif tmp(1)== 7, HDR.PhysDimCode = 544;  %% '%'
242                        elseif tmp(1)== 8, HDR.PhysDimCode = 6048; %% °C
243                        elseif tmp(1)== 9, HDR.PhysDimCode = 2528; %% 1/min
244                        elseif tmp(1)==10, HDR.PhysDimCode = 4264; %% 1/s
245                        elseif tmp(1)==11, HDR.PhysDimCode = 4288; %% Ohm
246                        elseif tmp(1)==12, HDR.PhysDimCode = 4160; %% A
247                        elseif tmp(1)==13, HDR.PhysDimCode = 65376; %% r.p.m.
248                        elseif tmp(1)==14, HDR.PhysDimCode = 4032; %% W
249                        elseif tmp(1)==15, HDR.PhysDimCode = 6448; %% dB
250                        elseif tmp(1)==16, HDR.PhysDimCode = 1731; %% kg';
251                        elseif tmp(1)==17, HDR.PhysDimCode = 3968; %% J';
252                        elseif tmp(1)==18, HDR.PhysDimCode = 6016; %% dyne s m-2 cm-5';
253                        elseif tmp(1)==19, HDR.PhysDim 	   = 'k';
254                        elseif tmp(1)==20, HDR.PhysDimCode = 3040; %% L/s';
255                        elseif tmp(1)==21, HDR.PhysDimCode = 3072; %% L/m';
256                        elseif tmp(1)==22, HDR.PhysDimCode = 4480; %% cd';
257                        elseif tmp(1)==23, HDR.PhysDim     = '';
258                        elseif tmp(1)==24, HDR.PhysDim     = '';
259                        elseif tmp(1)==25, HDR.PhysDim     = '';
260                        end;
261                        e = 10^tmp(2);
262                        len = len - 2;
263                        if     len == 1; [tmp,count] = fread(HDR.FILE.FID,1,'int8');
264                        elseif len == 2; [tmp,count] = fread(HDR.FILE.FID,1,'int16');
265                        elseif len == 3;
266                                %[tmp,count] = fread(HDR.FILE.FID,1,'bit24');
267                                [tmp,count] = fread(HDR.FILE.FID,3,'uint8');
268                                tmp = (2.^[16,8,0])*tmp;
269                        elseif len == 4; [tmp,count] = fread(HDR.FILE.FID,1,'int32');
270                        end;
271                        HDR.Cal = tmp*e;
272
273                elseif tag==13;          % offset
274                        [tmp,count] = fread(HDR.FILE.FID,1,gdfdatatype(HDR.GDFTYP));
275                        HDR.Off=tmp;
276
277                elseif tag==14;          % compression
278                        %[tmp,count] = fread(HDR.FILE.FID,[1,len],'uchar')
279                        [HDR.MFER.CompressionCode,count] = fread(HDR.FILE.FID,1,'uint16');
280                        [HDR.MFER.DataLength1,count] = fread(HDR.FILE.FID,1,'uint32');
281                        [HDR.MFER.DataLength2,count] = fread(HDR.FILE.FID,1,'uint32');
282                        [tmp,count] = fread(HDR.FILE.FID,[1,len],'uchar');
283                        HDR.tag14=char(tmp);
284                        HDR.FLAG.Compresssion=tmp;
285
286                elseif tag==17;
287                        [tmp,count] = fread(HDR.FILE.FID,[1,len],'uchar');
288                        HDR.tag17 = tmp;
289
290                elseif tag==18;       % null value
291                        [tmp,count] = fread(HDR.FILE.FID,1,gdfdatatype(HDR.GDFTYP));
292                        HDR.MFER.NullValue = tmp;
293
294                elseif tag==21;          %
295                        [tmp,count] = fread(HDR.FILE.FID,[1,len],'uchar');
296                        HDR.tag21=char(tmp);
297
298                elseif tag==22;          %
299                        [tmp,count] = fread(HDR.FILE.FID,[1,len],'uchar');
300                        HDR.comment=char(tmp);
301
302                elseif tag==23;          %
303                        [tmp,count] = fread(HDR.FILE.FID,[1,len],'uchar');
304                        HDR.tag23 = char(tmp);
305
306                elseif tag==30;          %
307			if isfield(HDR,'MFER');
308				if isfield(HDR.MFER,'SPR');
309	                                HDR.AS.spb = sum(HDR.MFER.SPR);
310				else
311	                                HDR.AS.spb = HDR.SPR*HDR.NS;
312        	                        HDR.MFER.SPR = HDR.SPR(ones(1,HDR.NS));
313				end;
314			end;
315
316                        HDR.SPR = HDR.MFER.SPR(1);
317                        for k=2:HDR.NS,
318                                HDR.SPR = lcm(HDR.SPR,HDR.MFER.SPR(k));
319                        end;
320
321                        HDR.FRAME.N = HDR.FRAME.N + 1;
322                        HDR.FRAME.POS(HDR.FRAME.N) = ftell(HDR.FILE.FID);
323                        HDR.FRAME.TYP(HDR.FRAME.N) = HDR.GDFTYP;
324                        nos = len/(HDR.AS.bps*HDR.AS.spb);
325                        HDR.FRAME.sz(HDR.FRAME.N,1:5) = [HDR.AS.spb,nos,HDR.NRec,HDR.NS,len];
326                        HDR.FRAME.Fs(HDR.FRAME.N) = HDR.SampleRate;
327
328                        fseek(HDR.FILE.FID,len,'cof');
329
330
331                elseif tag==63;
332                        chansel = mod(len,128)+1;
333                        k = 1;
334                        while len > 127,
335                                [len, count] = fread(HDR.FILE.FID,1,'uchar');
336                                k = k + 1;
337                                chansel(k)  = mod(len,128)+1;
338                        end
339
340                        [len, count] = fread(HDR.FILE.FID,1,'uchar');
341                        if 0,
342                        elseif len<128,
343                                while len,
344                                        tag2 = fread(HDR.FILE.FID,1,'uchar');
345                                        len2 = fread(HDR.FILE.FID,1,'uint8');
346                                        len = len - 2 - len2;
347                                        if 0,
348                                        elseif (tag2 == 4),
349                                                if len == 0;
350                                                        tmp = NaN;
351                                                elseif len == 1;
352                                                        [tmp,count] = fread(HDR.FILE.FID,1,'int8');
353                                                elseif len == 2;
354                                                        [tmp,count] = fread(HDR.FILE.FID,1,'int16');
355                                                elseif len == 3;
356                                                        %[tmp,count] = fread(HDR.FILE.FID,1,'bit24');
357                                                        [tmp,count] = fread(HDR.FILE.FID,3,'uint8');
358                                                        tmp = (2.^[16,8,0])*tmp;
359                                                elseif len == 4;
360                                                        [tmp,count] = fread(HDR.FILE.FID,1,'int32');
361                                                else
362                                                        fprintf(2,'Error MWFOPEN: len=%i exceeds max length (4) in tag 04h\n',len);
363                                                end;
364                                                %[HDR.SPR,count] = fread(HDR.FILE.FID,[1,len],'uchar');
365                                                HDR.MFER.SPR(chansel) = tmp;
366                                                HDR.SPR = lcm(tmp,HDR.SPR);
367
368                                        elseif (tag2 == 12),
369                                                [tmp, count] = fread(HDR.FILE.FID,1,gdfdatatype(HDR.GDFTYP));
370                                                HDR.Cal(chansel) = tmp;
371                                        elseif (tag2 == 13),
372                                                [tmp, count] = fread(HDR.FILE.FID,1,gdfdatatype(HDR.GDFTYP));
373                                                HDR.Off(chansel) = tmp;
374                                        elseif (tag2 == 9),
375                                                [tmp, count] = fread(HDR.FILE.FID,[1,len2],'uchar');
376                                                if ~isfield(HDR,'Label')
377                                                        HDR.Label(chansel,:) = ECG12LeadsCodes{tmp};
378                                                else
379                                                        HDR.Label(chansel,1:length(ECG12LeadsCodes{tmp})) = ECG12LeadsCodes{tmp};
380                                                end;
381                                        else  % if (tag2 == 10),
382                                                fprintf(2,'Error MWFOPEN: Tag %i in channel-specific section not supported \n',tag2);
383                                                fclose(HDR.FILE.FID);
384                                                HDR.FILE.OPEN=0;
385                                                return;
386                                        end;
387                                        %fprintf(1,'\t%i',chansel);
388                                        %fprintf(1,'> [%i] Tag %i = %i: (%i) \n',ftell(HDR.FILE.FID),tag2,tmp,len2);
389                                end;
390                        else
391                                tag2 = 1; len2=1;
392                                while (tag2 || len2),
393                                        tag2 = fread(HDR.FILE.FID,1,'uchar');
394                                        len2 = fread(HDR.FILE.FID,1,'uint8');
395                                        %% this part is not tested yet
396                                        fprintf(1,'\t%i',chansel);
397                                        fprintf(1,'> [%i] Tag %i: (%i)\n',ftell(HDR.FILE.FID),tag2,len2);
398
399                                        if (len2 < 0) || (len2 > 127),
400                                                l   = mod(len2,128);
401                                                len2 = fread(HDR.FILE.FID,[l,1],'uchar');
402                                                %len = 256.^[0:l-1]*len;
403                                                len2 = 256.^[l-1:-1:0]*len2;
404                                        end;
405                                        [tmp, count] = fread(HDR.FILE.FID,[1,len],'uchar');
406                                end;
407                        end;
408                        if isfield(HDR,'Label')
409                                HDR.Label = char(HDR.Label);
410                        end;
411
412                elseif tag==64;     % Preamble
413                        [tmp,count] = fread(HDR.FILE.FID,[1,len],'uint8');
414                        HDR.TYPE='MFER';
415
416                elseif tag==65;     % Events
417                        N = HDR.EVENT.N + 1;
418                        HDR.EVENT.N = N;
419			for k=1:N,
420	                        [HDR.EVENT.TYP(k),count] = fread(HDR.FILE.FID,1,'uint16');
421        	                if len>5,
422                	                [HDR.EVENT.POS(k),count] = fread(HDR.FILE.FID,1,'uint32');
423                        	end;
424	                        if len>9,
425        	                        [HDR.EVENT.DUR(k),count] = fread(HDR.FILE.FID,1,'uint32');
426                	        end;
427                        	if len>10,
428                                	[HDR.EVENT.Desc{k},count] = fread(HDR.FILE.FID,len-10,'uint8');
429	                        end;
430                        end;
431
432                elseif tag==67;     % Sample Skew
433                        [tmp,count] = fread(HDR.FILE.FID,1,'int16');
434                        HDR.SampleSkew = tmp;
435
436                elseif tag==129;     % Patient Name
437                        [tmp,count] = fread(HDR.FILE.FID,[1,len],'uint8');
438                        HDR.Patient.Name = char(tmp);
439
440                elseif tag==130;     % Patient Id
441                        [tmp,count] = fread(HDR.FILE.FID,[1,len],'uint8');
442                        HDR.PID = char(tmp);
443
444                elseif tag==131;     % Patient Age
445                        [tmp,count] = fread(HDR.FILE.FID,[1,len],'uint8');
446                        HDR.Patient.Age = char(tmp);
447
448                elseif tag==132;     % Patient Age
449                        [tmp,count] = fread(HDR.FILE.FID,[1,len],'uint8');
450                        HDR.Patient.Sex = char(tmp);
451
452                elseif tag==133;     % recording time
453                        [HDR.T0(1),count] = fread(HDR.FILE.FID,1,'int16');
454                        [HDR.T0(2:6),count] = fread(HDR.FILE.FID,[1,5],'uint8');
455                        [tmp,count] = fread(HDR.FILE.FID,[1,2],'int16');
456                        HDR.T0(6) = HDR.T0(6) + tmp(1)*1e-3 + tmp(2)+1e-6;
457
458                else
459                        [tmp,count] = fread(HDR.FILE.FID,[1,len],'uint8');
460                        %fprintf(1,'[%i %i] Tag %i: (%i) %s\n',ftell(HDR.FILE.FID),count,tag,len,char(tmp));
461                end;
462                % fprintf(1,'[%i %i] Tag %i: (%i)\n',ftell(HDR.FILE.FID),count,tag,len);
463                %                        count = 1;
464                %                        pause
465                tag = fread(HDR.FILE.FID,1,'uchar');
466       end;
467
468        HDR.HeadLen = ftell(HDR.FILE.FID);
469        HDR.FILE.POS  = 0;
470        HDR.Calib = sparse([HDR.Off(ones(1,HDR.NS/length(HDR.Off)));eye(HDR.NS)]);
471        HDR.Calib = HDR.Calib * sparse(1:HDR.NS,1:HDR.NS,HDR.Cal);
472end;
473
474