function [v t] = isfread (filename)
% isfread - will read the .ISF files produced by TEK MSO4000 oscilloscopes
%
% useage:   [rtnData, headData] = isfread ('filename')
% where:    rtnData     - is a struct with the x and y data returned in 
%                         rtnData.x and rtnData.y respectively 
%           headData    - is a struct with all the header data returned in
%                         different fields
%           'filename'  - is a string with the name of the file to be
%                         extracted
%
% Example:  filename = 'TEK00000CH1.ISF';
%           [data, header] = isfread (filename);
%           plot(data.x,data.y)
%
% The returned data is pre scaled using the information contained in the
% header of the ISF file.
%
% * Written 1/25/2009 by Wenwei Qiao *
% Modified header flags to work with MDO 3014 scope 3/25/2014 by Dennis Berridge

fileID = fopen(filename,'r');

% read ASCII header
header_tmp = fread(fileID, 500)';
header = char(header_tmp);

headData = parseHead(header);

fseek(fileID, 0, 'eof');
dataOffset =  - headData.NR_P*headData.BYT_N;
fseek(fileID, dataOffset, 'cof');

if (headData.BYT_N==1)
    inData = fread(fileID, headData.NR_P, 'int8');
else
    inData = fread(fileID, headData.NR_P, 'int16',  'ieee-be');
end

fclose(fileID);

lowerXLimit = headData.XZE;
upperXLimit = ((headData.NR_P-1)* headData.XIN  + headData.XZE);
t  = [lowerXLimit : headData.XIN : upperXLimit]';
v   = headData.YMU*(inData-headData.YOF) + headData.YZE;




% parseHead - used to parse and convert the header data into a more
% useful structure.
function headData = parseHead(header)

headData.NR_P       = getParamNum(header, 'NR_P'    ); 
headData.BYT_N		= getParamNum(header, 'BYT_N'	); 
headData.BIT_N		= getParamNum(header, 'BIT_N'	); 
headData.XIN		= getParamNum(header, 'XINC'	 	);
headData.XZE		= getParamNum(header, 'XZER'	 	);
headData.PT_O		= getParamNum(header, 'PT_OF' 	);
headData.YMU		= getParamNum(header, 'YMUL'  	);
headData.YOF		= getParamNum(header, 'YOF'  	);
headData.YZE		= getParamNum(header, 'YZER'  	);
headData.YSCALE		= getParamNum(header, 'YSCALE'	);
headData.HSCALE		= getParamNum(header, 'HSCALE'	);
headData.YPOS 		= getParamNum(header, 'YPOS'	);
headData.YOFFSET	= getParamNum(header, 'YOFFSET'	);
headData.HDELAY		= getParamNum(header, 'HDELAY'	);

headData.ENC        = getParamStr(header, 'ENC',   ';');
headData.BN_F       = getParamStr(header, 'BN_F',  ';');
headData.BYT_O      = getParamStr(header, 'BYT_O', ';');
headData.WFI        = getParamStr(header, 'WFI',   '"');
headData.PT_F       = getParamStr(header, 'PT_F',  ';');
headData.XUN        = getParamStr(header, 'XUN',   '"');
headData.YUN        = getParamStr(header, 'YUN',   '"');

headData.CURV       = getCurvNum(header);

function rtnNum = getParamNum (headStr, cmdStr)
cmdLoc = findstr(headStr, cmdStr);
if (cmdLoc)
    headStr_tmp     = headStr(cmdLoc(1)+length(cmdStr)+1 : length(headStr)) ;
    [tmp, remJunk]  = strtok(headStr_tmp,';') ;
    rtnNum          = str2num(tmp);
else
    rtnNum =[];
end


function rtnStr = getParamStr(headStr, cmdStr, dlm)
cmdLoc = findstr(headStr, cmdStr);
if (cmdLoc)
    headStr_tmp     = headStr(cmdLoc(1)+length(cmdStr)+1 : length(headStr)) ;
    [rtnStr,remStr] = strtok(headStr_tmp, dlm) ;
else
    rtnStr=[];
end


function rtnNum = getCurvNum (headStr)
cmdStr='CURV #';
cmdLoc = findstr(headStr, cmdStr);
if (cmdLoc)
    headStr_tmp     = headStr(cmdLoc(1)+length(cmdStr) : length(headStr)) ;
    curvNum_tmp     = headStr_tmp(1);
    curvNum         = str2num(curvNum_tmp);
    tmp             = headStr_tmp(2:curvNum+1) ;
    rtnNum          = str2num(tmp);
else
    rtnNum=[];
end
