% Created by Ralf Bachmayer 
% October 2008
% reads the Imagenex *.83p file format without the intensity bytes
% based on 83p(single Head Profile)DataFormat.pdf
%
% function out_struct = read_83P(file_name)
% file_name shouldcontain the full path if necessary
%out_struct = 
%
%          file_type: '83P'
%      Software_vers: 'Vers 1.00'
%           Date_str: [char]
%           Time_str: [char]
%          hund_secs: [double]
%           Date_mat: [double]
%        GPS_lat_deg: [double]
%        GPS_lat_min: [double]
%        GPS_lon_deg: [double]
%        GPS_lon_min: [double]
%    GPS_speed_in_kn: [double]
%        GPS_heading: [double] in Degrees
%        No_of_Beams: [double]
%           RNG_beam: [double]
%           ANG_beam: [double]
%          Time_secs: [ouble]
%             X_beam: [double] NOT a position it is only an
%             increasing index
%             Y_beam: [double] [m]
%             Z_beam: [double] [m]

% 
%
function Delta_T_struct = read_83P(file_name)
%
fid=fopen(file_name,'r');
for J=1:500 % this is for reading a limitted number of pings 
              % if used comment out next three lines 
%J=0;
%while (feof(fid)==0)
%    J=J+1;
% Reading the header, each ping comes with its own header
% General housekeeping
    Delta_T_struct.file_type = fread(fid,3,'*char')';
    Delta_T_struct.Software_vers = ['Vers 1.0' num2str(fread(fid,1))];
    N_bytes_bin = fread(fid,2);
    N_bytes = N_bytes_bin(1)*256+N_bytes_bin(2);
    
    foo = fread(fid,2);
% Data and time related info    
    Delta_T_struct.Date_str(J,:) = fread(fid,12,'*char')';
    Delta_T_struct.Time_str(J,:) = fread(fid,9,'*char')';
    Delta_T_struct.hund_secs(J) = str2num(fread(fid,4,'*char')');
    Delta_T_struct.Date_mat(J)=datenum([Delta_T_struct.Date_str(J,:) Delta_T_struct.Time_str(J,:)])+Delta_T_struct.hund_secs(J)/(60*60*24);
% for later I keep the first time stamp    
    if J==1
        START_TIME = Delta_T_struct.Date_mat;
    end
% Reading the GPS information lat, lon speed, heading    
    GPS_lat = fread(fid,14,'*char');
    Delta_T_struct.GPS_lat_deg(J) = str2double(GPS_lat(2:3));
    Delta_T_struct.GPS_lat_min(J) = str2double(GPS_lat(5:13)');
    %
    GPS_lon = fread(fid,14,'*char');
    Delta_T_struct.GPS_lon_deg(J) = str2double(GPS_lon(2:3));
    Delta_T_struct.GPS_lon_min(J) = str2double(GPS_lon(5:13)');
    %
    Delta_T_struct.GPS_speed_in_kn(:,J) = fread(fid,1,'int8')/10;
    GPS_heading_bin=fread(fid,2);
    Delta_T_struct.GPS_heading(:,J) = bitor(bitshift(GPS_heading_bin(1),8),GPS_heading_bin(2))/10;
% We have no pitch,roll and heading sensor read it anyway    
    Pitch_word = fread(fid,2);
    Pitch_flag = bitget(Pitch_word(1),8);
    if Pitch_flag == 0
        Pitch_angle = 0;
    elseif Pitch_flag == 1
        Pitch_angle = (bitor(bitshift(bitand(Pitch_word(1),01111111),8),Pitch_word(2))-900)/10;
    end
    %
    Roll_word = fread(fid,2);
    Roll_flag = bitget(Roll_word(1),8);
    if Roll_flag == 0
        Roll_angle = 0;
    elseif Roll_flag == 1
        Roll_angle = (bitor(bitshift(bitand(Roll_word(1),01111111),8),Roll_word(2))-900)/10;
    end
    %
    Heading_word = fread(fid,2);
    Heading_flag = bitget(Heading_word(1),8);
    if Heading_flag == 0
        Heading_angle = 0;
    elseif Heading_flag == 1
        Heading_angle = bitor(bitshift(bitand(Heading_word(1),01111111),8),Heading_word(2))/10;
    end
% Here comes the beam info settings at time of data collection
    % how many beams
    Beams_bin=fread(fid,2);
    Delta_T_struct.No_of_Beams(J) = bitor(bitshift(Beams_bin(1),8),Beams_bin(2));
    Max_NO_OF_BEAMS = max(Delta_T_struct.No_of_Beams);
    % how many samples per beam
    Samples_bin=fread(fid,2);
    No_of_samples = bitor(bitshift(Samples_bin(1),8),Samples_bin(2));
    % what sector are we scanning
    Sector_bin=fread(fid,2);
    Angle_of_sector = bitor(bitshift(Sector_bin(1),8),Sector_bin(2));
    % at what angle are we starting
    Angle_bin=fread(fid,2);
    Start_Angle = (bitor(bitshift(Angle_bin(1),8),Angle_bin(2))/100)-180;
    % what is the angle increment per beam
    Angle_inc = fread(fid,1)/100;
    % what acoustic range is the sonar set
    Range_bin=fread(fid,2);
    Range = bitor(bitshift(Range_bin(1),8),Range_bin(2));
    % what frequency are we set
    Freq_bin=fread(fid,2);
    Freq = bitor(bitshift(Freq_bin(1),8),Freq_bin(2));
    % Sound velocity?
    SND_word = fread(fid,2);
    SV_flag = bitget(SND_word(1),8);
    if SV_flag == 0
        SND_Vel = 1500;
    elseif SV_flag == 1
        SND_Vel = (bitor(bitshift((SND_word(1)-128),8),SND_word(2)))/10.0;
    end
    % Range resolution 
    RNG_res_bin=fread(fid,2);
    RNG_res = bitor(bitshift(RNG_res_bin(1),8),RNG_res_bin(2));
    %
    foo = fread(fid,2);
    %
    % Static tilt angle offset
    TLT_bin=fread(fid,2);
    TLT_ang = bitor(bitshift(TLT_bin(1),8),TLT_bin(2))-180;
    %
    % Repetion rate time beween pings [ms]
    REP_bin=fread(fid,2);
    REP_res = bitor(bitshift(REP_bin(1),8),REP_bin(2));
    %
    % Ping number(Is it the same as sample number?)
    PNG_bin=fread(fid,4);
    PNG_num = bitshift(PNG_bin(1),24)+bitshift(PNG_bin(2),16)+bitshift(PNG_bin(3),8)+PNG_bin(4)
    %
    foo = fread(fid,3);
    %
    % Sonar offset X,Y,Z
    Sonar_Xbin=fread(fid,4);
    Sonar_Xoff = bitshift(Sonar_Xbin(1),24)+bitshift(Sonar_Xbin(2),16)+bitshift(Sonar_Xbin(3),8)+Sonar_Xbin(4);
    Sonar_Ybin=fread(fid,4);
    Sonar_Yoff = bitshift(Sonar_Ybin(1),24)+bitshift(Sonar_Ybin(2),16)+bitshift(Sonar_Ybin(3),8)+Sonar_Ybin(4);
    Sonar_Zbin=fread(fid,4);
    Sonar_Zoff = bitshift(Sonar_Zbin(1),24)+bitshift(Sonar_Zbin(2),16)+bitshift(Sonar_Zbin(3),8)+Sonar_Zbin(4);
    %
    % system time 
    T_ms=fread(fid,5,'*char')';
    %
    % Intensity on or off
    INT_on=fread(fid,1);
    % Ping latency
    PNG_latency_bin = fread(fid,2);
    PNG_latency = (bitshift(PNG_latency_bin(1),8)+PNG_latency_bin(2))*100;
    % Data latency
    DAT_latency_bin = fread(fid,2);
    DAT_latency = (bitshift(DAT_latency_bin(1),8)+DAT_latency_bin(2))*100;
    %
    foo = fread(fid,134);
% end of header
    for i=1:Delta_T_struct.No_of_Beams(J)
        RNG_bin=fread(fid,2);
        Delta_T_struct.RNG_beam(i,J) = (bitshift(RNG_bin(1),8)+RNG_bin(2))*RNG_res/1000*SND_Vel/1500;
        if Delta_T_struct.No_of_Beams(J) <  Max_NO_OF_BEAMS
            Delta_T_struct.RNG_beam((Delta_T_struct.No_of_Beams(J)+1):Max_NO_OF_BEAMS,J)=NaN;
        end
        Delta_T_struct.ANG_beam(i,J) = (Start_Angle +(i-1)*Angle_inc)*pi/180;
        Delta_T_struct.Time_secs(i,J)=(Delta_T_struct.Date_mat(J)-START_TIME)*24*60*60;
        Delta_T_struct.X_beam(i,J) = J-1;
    end
    Delta_T_struct.Y_beam(:,J)=Delta_T_struct.RNG_beam(:,J).*sin(Delta_T_struct.ANG_beam(:,J));
    Delta_T_struct.Z_beam(:,J)=Delta_T_struct.RNG_beam(:,J).*cos(Delta_T_struct.ANG_beam(:,J));
    % if intensity is logged also this script has to be extended
    if INT_on
        sprintf('hello\n');
    else
        sprintf('increment\n');
    end
    
        
end
fclose(fid);
