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