function [mdata,r,ABS_Info,sdatenum,freq]=LoadABS(fname);
% LoadABS - Reads Aquatec ABS data files (*.aqa, .aqf)
% [mdata,r,ABS_Info,sdatenum,freq]=LoadABS(fname);
% Run
%    [mdata,r,ABS_Info,sdatenum,freq]=LoadABS(fname);
% where
%    mdata    - 3D array with ABS data with dimensions:
%               1 - profile
%               2 - time
%               3 - frequencies (1,2, or 3)
%    r        - vector of distances from the ABS
%    ABS_Info - ABS settings and system information
%    sdatenum - Matlab serial date number
%    freq     - sampling frequency

% Rewriten by Oleg Mouraenko, UF, 10/16/2003 - originally named readaqa_oleg.m
% from original version by Peter Traykovski, WHOI
% Last revised November 17, 2003

finfo=dir(fname);
flength=finfo.bytes;

fid = fopen(fname,'r');

while ftell(fid)< flength
   try
      command=freadchk(fid,1,'uint8');
      switch command;
      case 19; % command=19 - File_Type
         junk=freadchk(fid,1,'uint8');
         rec_size=freadchk(fid,1,'uint16');
         chksum=freadchk(fid,1,'uint16');
         sdata=freadchk(fid,rec_size/2,'uint16');
         
      case 20; % command=20 - ABS_Header
         junk=freadchk(fid,1,'uint8');
         rec_size=freadchk(fid,1,'uint16');
         chksum=freadchk(fid,1,'uint16');
         
         sysinfolen=freadchk(fid,1,'uint16');
         sysinfo=char(freadchk(fid,sysinfolen,'uchar'))';
         burstnum=freadchk(fid,1,'uint32');
         
         sdata=freadchk(fid,8,'uint8');
         second=str2num(dec2hex(sdata(2)));
         minute=str2num(dec2hex(sdata(3)));
         hour=str2num(dec2hex(sdata(4)));
         month=str2num(dec2hex(sdata(5)));
         day=str2num(dec2hex(sdata(6)));
         year=str2num(dec2hex(sdata(8)))*100+str2num(dec2hex(sdata(7)));
         sdatenum=datenum(year,month,day,hour,minute,second);
         numprofiles=freadchk(fid,1,'uint32'); %number of profiles measured
         wakeupsource=freadchk(fid,1,'uint16');
         
      case 21; % command=21 - ABS_Parameters
         junk=freadchk(fid,1,'uint8');
         rec_size=freadchk(fid,1,'uint16');
         chksum=freadchk(fid,1,'uint16');
         sdata=freadchk(fid,rec_size/2,'uint16')';
         
         samp_rate=sdata(1);
         avg_over=sdata(2);
         freq=samp_rate./avg_over; % sampling frequency in hz
         processingmode=sdata(3);
         dist_res=sdata(4)/1000; % in mm
         stor_res=sdata(5); % in bits
         maxnumfreqs=sdata(6); % max number of frequencies (3)
         % frequensies used
         tmp=fliplr(dec2bin(65536+sdata(7)))';
         freqs=str2num(tmp([1:maxnumfreqs]'))'; 
         numfreqs=sum(freqs); % number of frequencies 
         gains=sdata(8:10); % for each of the frequencies
         totnumbins=sdata(11); % total number of bins (128)
         %bins
         tmp=fliplr(dec2bin(sdata(12:19)))';
         bins=str2num(tmp(:))';        
         switch processingmode
         case {0,1};
            numbins=sum(bins); % number of bins
            r=(find(bins)-1)*dist_res; % vector of distances from ABS
         case 2; %average 2
            bins(2:2:end)=0;
            numbins=sum(bins); % number of bins
            r=(find(bins)-0.5)*dist_res; % vector of distances from ABS
         case 3; %average 4 
            bins(1:4:end)=0;
            bins=~bins;
            numbins=sum(bins); % number of bins
            r=(find(bins)+1.5)*dist_res; % vector of distances from ABS
         end;
         
      case 22; % command=22 - ABS_Data16
         junk=freadchk(fid,1,'uint8');
         rec_size=freadchk(fid,1,'uint16');
         chksum=freadchk(fid,1,'uint16');
         sdata=freadchk(fid,rec_size/2,'uint16')';
         if ~exist('mdata','var')
            % allocate memory
            mdata=zeros(numbins,numprofiles,numfreqs);
            lastprof=0; % last recorded profile
         end;
         for i=1:numfreqs
            mdata(:,lastprof+1,i)=sdata((i-1)*numbins+1:i*numbins);
         end;
         lastprof=lastprof+1;
         
      otherwise
         disp(sprintf('Command "%i" is not supported. Data omitted.',command));
         junk=freadchk(fid,1,'uint8');
         rec_size=freadchk(fid,1,'uint16');
         chksum=freadchk(fid,1,'uint16');
         sdata=freadchk(fid,rec_size,'uint8')';
      end;
   catch
      disp('Error detected. Data may be corrupted');
      mdata=mdata(:,1:lastprof,:);
   end;   
end; %while

fclose(fid);

ABS_Info = struct('sysinfolen',sysinfolen,...
   'sysinfo',sysinfo,...
   'burstnum',burstnum,...
   'year',year,...
   'month',month,...
   'day',day,...
   'hour',hour,...
   'minute',minute,...
   'second',second,...
   'numprofiles',numprofiles,...
   'readprofiles',lastprof,...
   'wakeupsource',wakeupsource,...
   'samp_rate',samp_rate,...
   'avg_over',avg_over,...
   'processingmode',processingmode,...
   'dist_res',dist_res,...
   'stor_res',stor_res,...
   'maxnumfreqs',maxnumfreqs,...
   'freqs',freqs,...
   'gains',gains,...
   'totnumbins',totnumbins,...  
   'bins',bins);

function M=freadchk(fid,count,type);
% Modification of FREAD function to check if all
% needed data was read.

M = fread(fid,count,type);
if length(M(:))<count
   disp('...error - unexpected End of File.');
   error('End of file');
end;
return;
   
