function D = IBWread(FN); % IBWread - read Igor wave from IBW file % D = IBWread('Foo.ibw') reads Igor file Foo.ibw into struct D. if exist('fullfilename', 'file'), FFN = fullfilename(FN, cd, '.ibw'); else, FFN = FN; end % read headers [D.binHeader, D.waveHeader, FFN] = readIBWheaders(FN); fid = fopen(FFN,'r'); fid = fopen(FFN,'r'); % For numeric waves, the type field is interpreted bitwise. One of the following bits, as represented by symbols defined in IgorBin.h, will be set: % % % #define NT_CMPLX 1 % Complex numbers. % % #define NT_FP32 2 % 32 bit fp numbers. % % #define NT_FP64 4 % 64 bit fp numbers. % % #define NT_I8 8 % 8 bit signed integer. Requires Igor Pro 2.0 or later. % % #define NT_I16 0x10 % 16 bit integer numbers. Requires Igor Pro 2.0 or later. % % #define NT_I32 0x20 % 32 bit integer numbers. Requires Igor Pro 2.0 or later. % % #define NT_UNSIGNED 0x40 % Makes above signed integers unsigned. Requires Igor Pro 3.0 or later. % NT_FP64 64-bit floating point (double) % NT_FP32 32-bit floating point (float) % NT_I32 32 bit integer (long) % NT_16 16 bit integer (short) % NT_I8 8 bit integer (char) datatype = D.waveHeader.type; CMPLX = rem(datatype,2); if CMPLX, datatype = datatype-1; end switch datatype, case 0, prec = '*char'; case 2, prec = 'single'; case 4, prec = 'double'; case 8, prec = 'int8'; case 16, prec = 'int16'; case 32, prec = 'int32'; case 64+8, prec = 'uint8'; case 64+16, prec = 'uint16'; case 64+32, prec = 'uint32'; otherwise, error('Invalid numerical datatype.'); end D.bname = D.waveHeader.bname; % The date/time is store as seconds since midnight, January 1, 1904. D.creationDate = local_igorTime2vec(D.waveHeader.creationDate); D.modDate = local_igorTime2vec(D.waveHeader.creationDate); switch D.binHeader.version, case 2, % The version 2 file has the following general layout. % BinHeader2 structure: 16 bytes % WaveHeader2 structure excluding wData field; 110 bytes % Wave data: Variable size D.Nsam = D.waveHeader.npnts; D.Ndim = 1; % X value for point p = hsA*p + hsB D.dx = D.waveHeader.hsA; D.x0 = D.waveHeader.hsB; D.x1 = D.x0+D.Nsam*D.dx; fseek(fid, 16+110, 'bof'); NN = D.Nsam*(1+double(CMPLX)); % if complex, read twice as many numbers D.y = fread(fid, NN, prec); if CMPLX, D.y = D.y(1:2:end) + i*D.y(2:2:end); end; % Re & Im values are interleaved case 5, % The version 5 file has the following general layout. % BinHeader5 structure 64 bytes % WaveHeader5 structure excluding wData field 320 bytes % Wave data Variable size % Optional wave dependency formula Variable size % Optional wave note data Variable size D.Nsam = D.waveHeader.npnts; D.Ndim = sum(D.waveHeader.nDim>0); % X offset & spacing (documentation is obscure) D.dx = D.waveHeader.sfA(1:D.Ndim); D.x0 = D.waveHeader.sfB(1:D.Ndim); D.x1 = nan; % D.x0+D.Nsam*D.dx; fseek(fid, 64+320, 'bof'); NN = D.Nsam*(1+double(CMPLX)); % if complex, read twice as many numbers if isequal(0,datatype), % text data % Number of bytes of wave data = wfmSize - (sizeof(WaveHeader5) - 4) NN = D.binHeader.wfmSize-320; D.y = fread(fid, NN, prec)'; else, % numerical data D.y = fread(fid, NN, prec); end if CMPLX, D.y = D.y(1:2:end) + i*D.y(2:2:end); end; % Re & Im values are interleaved if ~isempty(D.y) && D.Ndim>1, D.y = reshape(D.y, D.waveHeader.nDim(1:D.Ndim)); end end D.WaveNotes = local_readNotes(fid, D.binHeader); if isequal(0,datatype), % partition text data into lines using string indices stored @ eof D = local_partition_text(fid, D); end fseek(fid,0,'eof'); D.fileSize = ftell(fid); fclose(fid); %=============================== function DV=local_igorTime2vec(it); % igor time -> date vector a la Matlab % The date/time is store as seconds since midnight, January 1, 1904. Nsec_4year = 126230400; idate_1988 = 21*uint32(Nsec_4year); % # seconds between 1-jan-1904 & 1-jan-1988 it = double(it-idate_1988); % smaller numbers-> use ordinary numbers ("doubles") M4 = floor(it/Nsec_4year); YR = double(1988+4*M4); it = double(it-M4*Nsec_4year); last_it = it; while 1, % subtract years as long as they fit s = etime([YR+1 1 1 0 0 0], [YR 1 1 0 0 0]); if it