/* Include-file for reading .XTF files.  This file defines the
   structures currently defined in the .XTF file format.
*/

#define XTF_HEADER_SONAR                     0 // sidescan and subbottom
#define XTF_HEADER_NOTES                     1 // notes - text annotation
#define XTF_HEADER_BATHY                     2 // bathymetry (Seabat, Odom)
#define XTF_HEADER_ATTITUDE                  3 // TSS or MRU attitude (pitch, roll, heave, yaw)
#define XTF_HEADER_FORWARD                   4 // forward-look sonar (polar display)
#define XTF_HEADER_ELAC                      5 // Elac multibeam
#define XTF_HEADER_RAW_SERIAL                6 // Raw data from serial port
#define XTF_HEADER_EMBED_HEAD                7 // Embedded header structure
#define XTF_HEADER_HIDDEN_SONAR              8 // hidden (non-displayable) ping
#define XTF_HEADER_SEAVIEW_ANGLES            9 // Bathymetry (angles) for Seaview
#define XTF_HEADER_SEAVIEW_DEPTHS           10 // Bathymetry from Seaview data (depths)
#define XTF_HEADER_HIGHSPEED_SENSOR         11 // used by Klein (Cliff Chase) 0=roll, 1=yaw
#define XTF_HEADER_ECHOSTRENGTH             12 // Elac EchoStrength (10 values)
#define XTF_HEADER_GEOREC                   13 // Used to store mosaic params
#define XTF_HEADER_K5000_BATHYMETRY         14 // Bathymetry data from the Klein 5000
#define XTF_HEADER_HIGHSPEED_SENSOR2        15 // High speed sensor from Klein 5000

#define FMT_XTF 123 // unique ID for all XTF files.

typedef int                 BOOL;
//#define FALSE		    0
//#define TRUE		    (!FALSE)

typedef unsigned char	    BYTE;
typedef unsigned short      WORD;
typedef unsigned long       DWORD;
typedef unsigned int	    UINT;
typedef signed long         LONG;

// Channel information structure (contained in the file header).
// One-time information describing each channel.  64 bytes long.
// This is data pertaining to each channel that will not change
// during the course of a run.
///////////////////////////////////////////////////////////////////////////////
typedef struct {
   BYTE TypeOfChannel;     // PORT, STBD, SBOT or BATH
   BYTE SubChannelNumber;
   WORD CorrectionFlags;   // 1=raw, 2=Corrected
   WORD UniPolar;          // 0=data is bipolar, 1=data is unipolar

   WORD BytesPerSample;    // 1 or 2
   DWORD Reserved;         // Previously this was SamplesPerChannel.  Isis now supports
                           // the recording of every sample per ping, which means that
                           // number of samples per channel can vary from ping to ping
                           // if the range scale changes.  Because of this, the 
                           // NumSamples value in the XTFPINGCHANHEADER strcture (below)
                           // holds the number of samples to read for a given channel.
                           // For standard analog systems, this Reserved value is still
                           // filled in with 1024, 2048 or whatever the initial value is
                           // for SamplesPerChannel.

   char ChannelName[16];   // Text describing channel.  i.e., "Port 500"

   float VoltScale;        // How many volts is represented by max sample value.  Typically 5.0.
   float Frequency;        // Center transmit frequency
   float HorizBeamAngle;   // Typically 1 degree or so
   float TiltAngle;        // Typically 30 degrees
   float BeamWidth;        // 3dB beam width, Typically 50 degrees

                           // Orientation of these offsets:
                           // Positive Y is forward
                           // Positive X is to starboard
                           // Positive Z is down.  Just like depth.
                           // Positive roll is lean to starboard
                           // Positive pitch is nose up
                           // Positive yaw is turn to right

   float OffsetX;          // These offsets are entered in the 
   float OffsetY;          // Multibeam setup dialog box.
   float OffsetZ;

   float OffsetYaw;        // If the multibeam sensor is reverse
                           // mounted (facing backwards), then
                           // OffsetYaw will be around 180 degrees.
   float OffsetPitch;      
   float OffsetRoll;

   WORD  BeamsPerArray;    // For forward look only (i.e., Sonatech DDS)

   char ReservedArea2[54];

} SChanInfo;


   
// XTF File header.
// Total of 1024 bytes.
///////////////////////////////////////////////////////////////////////////////
typedef struct {
   BYTE FileFormat;        // 50 for Q-MIPS file format, 51 for Isis format
   BYTE SystemType;        // Type of system used to record this file.  202=Isis
   char RecordingProgramName[8];    // Example: "Isis"
   char RecordingProgramVersion[8]; // Example: "1.72"
   char SonarName[16];     // Name of server used to access sonar.  Example: "C31_SERV.EXE"
   WORD SonarType;         // K2000=5, DF1000=7, SEABAT=8
   char NoteString[64];    // Notes as entered in the Sonar Setup dialog box
   char ThisFileName[64];  // Name of this file. Example:"LINE12-B.XTF"

   WORD NavUnits;          // 0=METERS or 3=DEGREES

   WORD NumberOfSonarChannels;  // if > 60, header goes to 8K in size
   WORD NumberOfBathymetryChannels;
   WORD NumberOfForwardLookArrays;
   WORD NumberOfEchoStrengthChannels;
   WORD Reserved1;
   WORD Reserved2;
   WORD Reserved3;
   WORD Reserved4;

   // nav system parameters
   ///////////////////////////
   BYTE     ProjectionType[12];       // Not currently used
   BYTE     SpheriodType[10];         // Not currently used
   long     NavigationLatency;        // milliseconds, latency of nav system (usually GPS)
                                      // This value is entered on the
                                      // Serial port setup dialog box.  
                                      // When computing a position, Isis will
                                      // take the time of the navigation 
                                      // and subtract this value.

   float    OriginY;                  // Not currently used
   float    OriginX;                  // Not currently used

                                      // Orientation of these offsets:
                                      // Positive Y is forward
                                      // Positive X is to starboard
                                      // Positive Z is down.  Just like depth.
                                      // Positive roll is lean to starboard
                                      // Positive pitch is nose up
                                      // Positive yaw is turn to right

   float    NavOffsetY;               // These offsets are entered in
   float    NavOffsetX;               // the multibeam setup dialog box.
   float    NavOffsetZ;               
   float    NavOffsetYaw;

   float    MRUOffsetY;               // These offsets are entered in
   float    MRUOffsetX;               // the multibeam setup dialog box
   float    MRUOffsetZ;               

   float    MRUOffsetYaw;          
   float    MRUOffsetPitch;
   float    MRUOffsetRoll;        

                          // note: even 128-byte boundary to here

   SChanInfo ChanInfo[6];  // Each CHANINFO struct is 128 bytes.
                          // If more than 6 channels needed, header record
                          // grows 1K in size for each additional 8 channels.
} SXtfFileHeader;


// The XTFATTITUDEDATA structure used to store information from a TSS or 
// MRU motion sensor device.  This is usually high-resolution data
// (updating 20 times per second or more) and is needed when processing
// multibeam bathymetric data.  When TSS or MRU is selected as a serial device,
// the data is received and decoded.  As the attitude information is decoded,
// the values are filled into the following structure and then saved to the 
// XTF file.
//
// Attitude data packet, 64 bytes in length.
///////////////////////////////////////////////////////////////////////////////
typedef struct {
   // 
   // Type of header
   //
   WORD MagicNumber;      // Always set to 0xFACE
   BYTE HeaderType;       // XTF_HEADER_ATTITUDE (3)
   BYTE SubChannelNumber; // When HeaderType is Bathy, indicates which head
   WORD NumChansToFollow; // If Sonar Ping, Number of channels to follow
   WORD Reserved1[2];

   DWORD NumBytesThisRecord; // Total byte count for this ping including this ping header
                             // Note: Isis records data packets in multiples of 64 bytes.
							 // If the size of the data packet is not an exact multiple of
							 // 64 bytes, zeros are padded at the end packet and this value
							 // will be promoted to the next 64-byte granularity.  In all
							 // cases, this value will be the EXACT size of this packet
							 //
   DWORD Reverved2[4];

   // will be followed by attitude data even to 64 bytes
   float Pitch;   // positive value is nose up
   float Roll;    // positive value is roll to starboard
   float Heave;   // positive value is sensor up
                  // Note: The TSS sends heave positive up.  The MRU
                  // sends heave positive down.  In order to make the 
                  // data logging consistent, the sign of the MRU's 
                  // heave is reversed before being stored in this field.

   float Yaw;     // positive value is turn right
   DWORD TimeTag; // time ref. given in milliseconds

   float Heading; // In degrees, as reported by MRU.  
                  // TSS doesn't report heading, so when using a TSS 
                  // this value will be the most recent ship gyro value 
                  // as received from GPS or from any serial port using 
                  // 'G' in the template.

   BYTE  Reserved3[10];

} SXtfAttitudeData;


// Sonar or Bathy Ping header
// The data here can change from ping to ping but will pertain to all
// channels that are at the same time as this ping.  256 bytes in length.
///////////////////////////////////////////////////////////////////////////////
typedef struct {

   // 
   // Type of header
   //
   WORD MagicNumber;      // Set to 0xFACE
   BYTE HeaderType;       // Typically XTF_HEADER_SONAR (0), XTF_HEADER_BATHY (2),
                          // XTF_HEADER_ATTITUDE
   BYTE SubChannelNumber; // When HeaderType is Bathy, indicates which head
                          // When sonar, which ping of a batch (Klein 5000: 0..4)

   WORD NumChansToFollow; // If Sonar Ping, Number of channels to follow
   WORD Reserved1[2];

   DWORD NumBytesThisRecord; // Total byte count for this ping including this ping header

   //
   // Date and time of the ping
   //
   WORD  Year;          // Computer date when this record was saved
   BYTE  Month;
   BYTE  Day;
   BYTE  Hour;          // Computer time when this record was saved
   BYTE  Minute;
   BYTE  Second;
   BYTE  HSeconds;      // hundredths of seconds (0-99)
   WORD  JulianDay;     // Number of days since January 1

   //
   // General information
   //
   WORD CurrentLineID;     // [i] Current line ID from serial port
   WORD EventNumber;       // [O] Last logged event number

   DWORD PingNumber;       // Counts consecutively from 0 and increments 
                           //   for each update.  Note that the
                           //   counters are different between sonar
                           //   and bathymetery updates.

   float SoundVelocity;    // m/s, Round trip, defaults to 750. 
                           //   Can be changed on Isis menu.  This
                           //   value is never computed and can only be 
                           //   changed manually by the user. Also see 
                           //   ComputedSoundVelocity below.

   float OceanTide;        // [{t}] Ocean tide in meters.  Can be
                           // changed by the user on the Configure 
                           // menu in Isis.
   DWORD Reserved2;        // Reserved for future use
   
   //
   // Raw CTD information.  The Freq values are those sent up by the
   // SeaBird CTD.  The Falmouth Scientific CTD sends up computed data.
   float ConductivityFreq; // [Q] Conductivity frequency in Hz
   float TemperatureFreq;  // [b] Temperature frequency in Hz
   float PressureFreq;     // [0] Pressure frequency in Hz
   float PressureTemp;     // [;] Pressure Temperature (Degrees C)

   // 
   // Computed CTD information.  When using a SeaBird CTD, these
   // values are computed from the raw Freq values (above).
   //
   float Conductivity;     // [{c}] Conductivity in S/m can be computed from [Q]
   float WaterTemperature; // [{w}] Water temperature in C, can be computed from [b]
   float Pressure;         // [{p}] Water pressure in psia, can be computed from [0]
   float ComputedSoundVelocity;  // Meters per second, computed from
                                 // Conductivity, WaterTemperature and 
                                 // Pressure using the Chen Millero
                                 // formula (1977) formula (JASA,62,1129-1135).


   //
   // Sensors information
   //
   float MagX;             // [e] X-axis magnetometer data, mgauss
   float MagY;             // [w] Y-axis magnetometer data, mgauss
   float MagZ;             // [z] Z-axis magnetometer data, mgauss

                           // Auxillary values can be used to store
                           // and display any value at the user's
                           // discretion.  The are not used in
                           // any calculation in Isis, Target or Vista.

   float AuxVal1;          // [1] Auxillary value.  Displayed in the 
   float AuxVal2;          // [2] Auxillary value   "Sensors" window
   float AuxVal3;          // [3] Auxillary value   available by selecting
   float AuxVal4;          // [4] Auxillary value   Window->Text->Sensors.
   float AuxVal5;          // [5] Auxillary value
   float AuxVal6;          // [6] Auxillary value

   float SpeedLog;         // [s] Speed log sensor on towfish - knots. This isn't fish speed!
   float Turbidity;        // [|] turbidity sensor (0 to +5 volts) stored times 10000

   //
   // Ship Navigation information.  These values are stored only
   // and are not part of any equation or computation in Isis.
   //
   float ShipSpeed;        // [v] Speed of ship in knots.  Stored
   float ShipGyro;         // [G] Ship gyro in degrees
   double ShipYcoordinate; // [y] Ship latitude or northing
   double ShipXcoordinate; // [x] Ship longitude or easting

   WORD ShipAltitude;      // Decimeters (meters*10, stored only)
   WORD ShipDepth;         // Decimeters (meters*10, stored only)

   // 
   // Sensor Navigation information
   //
   BYTE FixTimeHour;       // [H] Hour of most recent nav update
   BYTE FixTimeMinute;     // [I] Minute of most recent nav update
   BYTE FixTimeSecond;     // [S] Second of most recent nav update
                           // Note that the time of the nav is
                           // adjusted by the NavLatency stored in 
                           // the XTF file header.
   BYTE Reserved4;
   float SensorSpeed;      // [V] Speed of the in knots.  Used for
                           //   speed correction and position calculation.
   float KP;               // [{K}] Kilometers Pipe
   double SensorYcoordinate; // [E] Sensor latitude or northing
   double SensorXcoordinate; // [N] Sensor longitude or easting
                             // Note: when NavUnits in the file header
                             // is 0, values are in meters (northings
                             // and eastings).  When NavUnits is 3,
                             // values are in Lat/Long.  Also see
                             // the Layback value, below.

   //
   // Tow Cable information
   //
   WORD SonarStatus;       // System status value, sonar dependant (displayed in Status window)
   WORD RangeToFish;       // [?] Slant range to fish * 10.  
                           //    Not currently used.
   WORD BearingToFish;     // [>] Bearing to towfish from ship * 100.  
                           //    Not currently used.
   WORD CableOut;          // [o] Amount of cable payed out in meters
                           //    Not currently used in Isis.
   float Layback;          // [l] Distance over ground from ship to fish.
                           //    When this value is non-zero, Isis
                           //    assumes that SensorYcoordinate and 
                           //    SensorXcoordinate need to be
                           //    adjusted with the Layback.  The sensor 
                           //    position is then computed using the 
                           //    current sensor heading and this layback 
                           //    value.  The result is displayed when a 
                           //    position is computed in Isis. 

   float CableTension;     // [P] Cable tension from serial port. Stored only.

   //      
   // Sensor Attitude information
   //
   float SensorDepth;        // [0] Distance from sea surface to
                             //   sensor.  The deeper the sensor goes, 
                             //   the bigger (positive) this value becomes.

   float SensorPrimaryAltitude; 
                             // [7] Distance from towfish to the sea
                             //   floor.  This is the primary altitude as 
                             //   tracked by the Isis bottom tracker or
                             //   entered manually by the user. 
                             //   Although not recommended, the user can 
                             //   override the Isis bottom tracker by 
                             //   sending the primary altitude over the 
                             //   serial port.  The user should turn the 
                             //   Isis bottom tracker Off when this is done.
                                   
   float SensorAuxAltitude;  // [a] Auxillary altitude.  This is an
                             //   auxillary altitude as transmitted by an 
                             //   altimeter and received over a serial port.
                             //   The user can switch betwen the Primary and 
                             //   Aux altitudes via the "options" button in 
                             //   the Isis bottom track window.

   float SensorPitch;        // [8] Pitch in degrees (positive=nose up)
   float SensorRoll;         // [9] Roll in degrees (positive=roll to stbd)
   float SensorHeading;      // [h] Fish heading in degrees

   // These Pitch, Roll, Heading, Heave and Yaw values are those received 
   // closest in time to this sonar or bathymetry update.  If a TSS or MRU
   // is being used with a multibeam/bathymetry sensor, the user should 
   // use the higher-resolution attitude data found in the XTFATTITUDEDATA 
   // structures.


   //
   // additional attitude data
   //
   float Heave;            // Sensor heave at start of ping. 
                           // Positive value means sensor moved up.
   float Yaw;              // Sensor yaw.  Positive means turn to right.
   DWORD AttitudeTimeTag;  // milliseconds - used to coordinate with millisecond 
                           // time value in Attitude packet

   //
   // Misc.
   //
   float DOT;              // Distance Off Track

   DWORD NavFixMilliseconds; //	millisecond clock value when nav received

   //
   // The Isis computer clock time when this ping was received.
   // May be different from ping time at start of this record if
   // the sonar time-stamped the data and the two systems aren't synced.
   // This time should be ignored in most cases.
   //
   unsigned char ComputerClockHour;
   unsigned char ComputerClockMinute;
   unsigned char ComputerClockSecond;
   unsigned char ComputerClockHsec;

   //
   // Additional Tow Cable and Fish information from Trackpoint
   //
   short FishPositionDeltaX;       // [{DX}] Stored as meters*3.0, supporting +/- 10000.0m (usually from trackpoint)
   short FishPositionDeltaY;       // [{DY}] X,Y offsets can be used instead of logged layback.
   unsigned char FishPositionErrorCode; // Error code for FishPosition delta x,y (typically reported by Trackpoint)

   //
   // Pad to make an even 256 bytes
   //
   BYTE ReservedSpace2[11]; // Currently unused

} SXtfPingHeader, SXtfBathHeader;



// Annotation record
// An annotation record is a line of text which can be saved to the
// file and is displayed in the "Notes" field on the Isis display.
// This text is displayed during playback.  Additionally, this text
// may be printed in realtime or in playback.  This can be activated
// in the Print Annotation dialog box.
///////////////////////////////////////////////////////////////////////////////
typedef struct {

   WORD MagicNumber;      // Set to 0xFACE
   BYTE HeaderType;       // XTF_HEADER_NOTES (1)
   BYTE SubChannelNumber;
   WORD NumChansToFollow;
   WORD Reserved[2];
   DWORD NumBytesThisRecord; // Total byte count for this update

   //
   // Date and time of the annotation
   //
   WORD  Year;
   BYTE  Month;
   BYTE  Day;
   BYTE  Hour;
   BYTE  Minute;
   BYTE  Second;
   BYTE  ReservedBytes[35];

   char  NotesText[256-56];

} SXtfNotesHeader;


// RAW ASCII data received over serial port
// These packets are stored in the XTF file on a per-serial-port
// basis.  To store the raw ASCII data for a given serial port, add 
// the token "{SAVEALL}" to the serial port template.  Use of this
// option is not generally recommended, since Isis already parses the
// data for all usefull information.

///////////////////////////////////////////////////////////////////////////////
typedef struct {

   WORD MagicNumber;      // Set to 0xFACE
   BYTE HeaderType;       // will be XTF_HEADER_RAW_SERIAL (7)
   BYTE SerialPort;  
   WORD Reserved2[3];
   DWORD NumBytesThisRecord; // Total byte count for this update

   //
   // Date and time raw ASCII data was posted to disk
   //
   WORD  Year;
   BYTE  Month;
   BYTE  Day;
   BYTE  Hour;
   BYTE  Minute;
   BYTE  Second;
   BYTE  HSeconds;      // hundredth of seconds (0-99)
   WORD  JulianDay;     // days since Jan 1.

   DWORD TimeTag;       // millisecond timer value
   WORD  StringSize;    // Number of valid chars in RawAsciiData string
   char  RawAsciiData[64-30]; // will be padded in 64-byte increments to make 
                              // structure an even multiple of 64 bytes

} SXtfRawSerialHeader;


// Ping Channel header 
// This is data that can be unique to each channel from ping to ping.
// Is is stored at the front of each channel of sonar data.
///////////////////////////////////////////////////////////////////////////////
typedef struct {

   WORD  ChannelNumber;    // Typically, 
                           // 0=port (low frequency)
                           // 1=stbd (low frequency)
                           // 2=port (high frequency)
                           // 3=stbd (high frequency)

   WORD  DownsampleMethod;  // 2=MAX, 4=RMS
   float SlantRange;       // Slant range of the data in meters
   float GroundRange;      // Ground range of the data in meters
                           //   (SlantRange^2 - Altitude^2)
   float TimeDelay;        // Amount of time (in seconds) to the start of recorded data
                           //   almost always 0.0
   float TimeDuration;     // Amount of time (in seconds) recorded
   float SecondsPerPing;   // Amount of time (in seconds) from ping to ping

   WORD  ProcessingFlags;  // 4=TVG, 8=BAC&GAC, 16=Filter, etc...
                           //   almost always 0
   WORD  Frequency;        // Center transmit frequency for this channel.
						   //   when non-zero, replaces value found in file
                           //   header CHANINFO struct ChanInfo->SamplesPerChannel.
                           //   This allows samples per channel to change on the fly.

   WORD InitialGainCode;   // Settings as transmitted by sonar
   WORD GainCode;
   WORD BandWidth;

   //
   // Contact information - updated when contacts are saved through Target.exe
   //
   DWORD ContactNumber;
   WORD  ContactClassification;
   unsigned char ContactSubNumber;
   unsigned char ContactType;


   DWORD NumSamples;            // Number of samples that will follow this structure.  The
                                // number of bytes will be this value multipied by the
								// number of bytes per sample (given in the file header)

   WORD  Reserved;              // Obsolete.
   float ContactTimeOffTrack;	// Time off track to this contact (stored in milliseconds)
   unsigned char ContactCloseNumber;
   unsigned char Reserved2;

   float FixedVSOP;             // Fixed along-track size of each ping, stored in cm.
                                //  on multibeam system with zero beam spread, this value
                                //  needs to be filled in to prevent Isis from calculating
                                //  along-track ground coverage based on beam spread and 
                                //  speed over ground.

   BYTE  ReservedSpace[6];      // reserved for future expansion

} SXtfPingChanHeader;


//// Eric creation to speed up the process 
typedef struct {
   WORD MagicNumber;      // Set to 0xFACE
   BYTE HeaderType;       // Typically XTF_HEADER_SONAR (0), XTF_HEADER_BATHY (2),
   BYTE dummy1;            //                           // 
   WORD Reserved1[3];
   DWORD NumBytesThisRecord; // Total byte count for this packet including this header
} SXtfCommonPartHeader ;

//
//
//	Bathy Data Packet
//
//

struct 	DATA_TIME
{
	DWORD	Seconds;	// seconds since 00:00:00, 1 January 1970
	DWORD	Millisecs;	// milliseconds, LSB = 1 ms
};


// Id = 0x01
struct R_THETA_9001
{
   	BYTE		synch_header[4];		// synch header {0xff, 0xff, 0x00, 0x00
   	BYTE      	packet_type;      		// identifier for packet type (0x11)
   	BYTE		packet_subtype;   		// identifier for packet subtype
	BYTE		date[6] ;				// date Y-M-D-H-M-S
	WORD		velocity ;				// programmed sound velocity (LSB = 1 m/sec)
   	WORD 		latency;          		// time from ping to output (milliseconds)
   	WORD 		sample_rate;      		// A/D sample rate (samples per second)
	WORD		range[60] ;				// range+quality flags
	WORD		checksum ;				// Checksum
} ;

// Id = 0x11
struct 	R_THETA_DATA_VERY_OLD
{
   	BYTE		synch_header[4];		// synch header {0xff, 0xff, 0x00, 0x00
   	BYTE      	packet_type;      		// identifier for packet type (0x11)
   	BYTE		packet_subtype;   		// identifier for packet subtype
   	DATA_TIME	data_time;        		// time of ping for data packet
   	WORD 		latency;          		// time from ping to output (milliseconds)
   	WORD 		velocity;         		// programmed sound velocity (LSB = 1 m/sec)
   	WORD 		sample_rate;      		// A/D sample rate (samples per second)
   	BYTE  		pulse_width;      		// transmit pulse width (microseconds)
   	WORD 		ping_rate;        		// Ping rate (pings per second * 1000)
   	WORD 		range_set;        		// range setting for SeaBat (meters )
   	WORD 		power;            		// power setting for SeaBat  	
										// bits	0-4 -	power (0 - 8)
										// bit	15	(0 = manual, 1 = auto)
	WORD 		gain;             		// gain setting for SeaBat
										// bits	0-6 -	gain (1 - 45)
										// bit 	14	(0 = fixed, 1 = tvg)
										// bit	15	(0 = manual, 1 = auto)
	short		projector;        		// projector setting
	BYTE		beam_width;       		// cross track receive beam width (degrees * 10)
	WORD		beam_count;       		// number of sets of beam data in packet
	WORD		range ; 				// [n] range for beam where n = Beam Count
//	BYTE  		quality[n/2];   		// packed quality array (two 4 bit values/char)
										// bit 0 - brightness test (0=failed, 1=passed)
										// bit 1 - colinearity test (0=failed, 1=passed)
										// bit 2 - amplitude bottom detect used
										// bit 3 - phase bottom detect used
										// bottom detect can be amplitude, phase or both
//	WORD 		checksum;         		// checksum for data packet
};


// ID = 0x12
struct 	RI_THETA_DATA_VERY_OLD
{
	BYTE		synch_header[4];		// synch header {0xff, 0xff, 0x00, 0x00
   	BYTE      	packet_type;      		// identifier for packet type (0x12)
   	BYTE		packet_subtype;			// identifier for packet subtype
   	DATA_TIME	data_time;        		// time of ping for data packet
   	WORD 		latency;          		// time from ping to output (milliseconds)
   	WORD 		velocity;         		// programmed sound velocity (LSB = 1 m/sec)
   	WORD 		sample_rate;      		// A/D sample rate (samples per second)
   	BYTE  		pulse_width;      		// transmit pulse width (microseconds)
   	WORD 		ping_rate;        		// Ping rate (pings per second * 1000)
   	WORD 		range_set;        		// range setting for SeaBat (meters )
   	WORD 		power;            		// power setting for SeaBat
										// bits	0-4 -	power (0 - 8)
										// bit	15	(0 = manual, 1 = auto)
  	WORD 		gain;             		// gain setting for SeaBat
										// bits	0-6 -	gain (1 - 45)
										// bit 	14	(0 = fixed, 1 = tvg)
										// bit	15	(0 = manual, 1 = auto)
  	short		projector;        		// projector setting
	BYTE		beam_width;       		// cross track receive beam width (degrees * 10)
	WORD		beam_count;       		// number of sets of beam data in packet
	WORD 		range; 					// [n] range for beam where n = Beam Count
//	BYTE  		quality[n/2];   		// packed quality array (two 4 bit values/char)
										// bit 0 - brightness test (0=failed, 1=passed)
										// bit 1 - colinearity test (0=failed, 1=passed)
										// bit 2 - amplitude bottom detect used
										// bit 3 - phase bottom detect used
										// bottom detect can be amplitude, phase or both
//	BYTE		intensity[n];   		// intensities at bottom detect
//	WORD 		checksum;         		// checksum for data packet
};


// ID = 0x13
struct  R_THETA_DATA_OLD 
{
   	BYTE		synch_header[4];		// synch header {0xff, 0xff, 0x00, 0x00
   	BYTE		packet_type;      		// identifier for packet type (0x13)
   	BYTE		packet_subtype;   		// identifier for packet subtype
   	DATA_TIME	data_time;				// time of ping for data packet
   	WORD 		latency;          		// time from ping to output (milliseconds)
   	WORD 		velocity;         		// programmed sound velocity (LSB = 1 m/sec)
   	WORD 		sample_rate;      		// A/D sample rate (samples per second)
   	BYTE	 	pulse_width;      		// transmit pulse width (microseconds)
   	WORD 		ping_rate;        		// Ping rate (pings per second * 1000)
   	WORD 		range_set;        		// range setting for SeaBat (meters )
   	WORD 		power;            		// power setting for SeaBat  	
										// bits	0-4 -	power (0 - 8)
										// bit	15	(0 = manual, 1 = auto)
	WORD 		gain;		          	// gain setting for SeaBat
										// bits	0-6 -	gain (1 - 45)
										// bit 	14	(0 = fixed, 1 = tvg)
										// bit	15	(0 = manual, 1 = auto)
	short		projector;		     	// projector setting 
	BYTE		tvg_spread;				// spreading coefficient for tvg * 4 
										// valid values = 0 to 240 (0.0 to 60.0 in 0.25 steps)
	BYTE		tvg_absorp;				// absorption coefficient for tvg
	BYTE	  	beam_width;       		// cross track receive beam width (degrees * 10)
	WORD       beam_count;		      	// number of sets of beam data in packet
	WORD 		range;					// [n] range for beam where n = Beam Count
										// range units = sample cells * 4
//	BYTE  		quality[n/2];   		// packed quality array (two 4 bit values/char)
										// bit 0 - brightness test (0=failed, 1=passed)
										// bit 1 - colinearity test (0=failed, 1=passed)
										// bit 2 - amplitude bottom detect used
										// bit 3 - phase bottom detect used
										// bottom detect can be amplitude, phase or both
//	WORD 		checksum;         		// checksum for data packet
};


// ID = 0x14
struct 	RI_THETA_DATA_OLD
{
   	BYTE		synch_header[4];		// synch header {0xff, 0xff, 0x00, 0x00
   	BYTE      	packet_type;      		// identifier for packet type (0x14)
   	BYTE		packet_subtype;			// identifier for packet subtype
   	DATA_TIME	data_time;        		// time of ping for data packet
   	WORD 		latency;          		// time from ping to output (milliseconds)
   	WORD 		velocity;         		// programmed sound velocity (LSB = 1 m/sec)
   	WORD 		sample_rate;      		// A/D sample rate (samples per second)
   	BYTE  		pulse_width;      		// transmit pulse width (microseconds)
   	WORD 		ping_rate;        		// Ping rate (pings per second * 1000)
   	WORD 		range_set;        		// range setting for SeaBat (meters )
   	WORD 		power;            		// power setting for SeaBat  	
										// bits	0-4 -	power (0 - 8)
										// bit	15	(0 = manual, 1 = auto)
	WORD 		gain;             		// gain setting for SeaBat
										// bits	0-6 -	gain (1 - 45)
										// bit 	14	(0 = fixed, 1 = tvg)
										// bit	15	(0 = manual, 1 = auto)
	short		projector;        		// projector setting 
	BYTE		tvg_spread;				// spreading coefficient for tvg * 4 
										// valid values = 0 to 240 (0.0 to 60.0 in 0.25 steps)
	BYTE		tvg_absorp;				// absorption coefficient for tvg
	BYTE  		beam_width;       		// cross track receive beam width (degrees * 10)
	WORD		beam_count;       		// number of sets of beam data in packet
	WORD 		range; 					// [n] range for beam where n = Beam Count
										// range units = sample cells * 4
//	BYTE  		quality[n];		   		// unpacked quality array (one 8 bit value/char)
										// bit 0 - brightness test (0=failed, 1=passed)
										// bit 1 - colinearity test (0=failed, 1=passed)
										// bit 2 - amplitude bottom detect used
										// bit 3 - phase bottom detect used
										// bottom detect can be amplitude, phase or both
//	WORD		intensity[n];   		// intensities at bottom detect * 8
//	WORD 		checksum;         		// checksum for data packet
};


// ID = 0x17
struct 	R_THETA_DATA
{
   	BYTE		synch_header[4];		// synch header {0xff, 0xff, 0x00, 0x00
   	BYTE      	packet_type;      		// identifier for packet type (0x17)
   	BYTE		packet_subtype;		  	// identifier for packet subtype
										// for dual head system, most significant bit (bit 7)
										// indicates which sonar head to associate with packet
										//	head 1 - bit 7 set to 0
										// 	head 2 -	bit 7 set to 1 		
	WORD 		latency;          		// time from ping to output (milliseconds)
	DATA_TIME	data_time;        		// time of ping for data packet
	DWORD		ping_number	;			// sequential ping number from sonar startup/reset
	DWORD		sonar_id;				// least significant four bytes of Ethernet address
	WORD		sonar_model;			// coded model number of sonar
	WORD		frequency;				// sonar frequency in KHz
	WORD 		velocity;         		// programmed sound velocity (LSB = 1 m/sec)
   	WORD 		sample_rate;      		// A/D sample rate (samples per second)
	WORD 		ping_rate;        		// Ping rate (pings per second * 1000)
   	WORD 		range_set;        		// range setting for SeaBat (meters )
   	WORD 		power;            		// power setting for SeaBat  	
										// bits	0-4 -	power (0 - 8)
	WORD 		gain;             		// gain setting for SeaBat
										// bits	0-6 -	gain (1 - 45)
										// bit 	14	(0 = fixed, 1 = tvg)
										// bit	15	(0 = manual, 1 = auto)
	WORD  		pulse_width;      		// transmit pulse width (microseconds)
	BYTE		tvg_spread;				// spreading coefficient for tvg * 4 
										// valid values = 0 to 240 (0.0 to 60.0 in 0.25 steps)
	BYTE		tvg_absorp;				// absorption coefficient for tvg
	BYTE     	projector_type;      	// bits 0-4 = projector type
										// 0 = stick projector
										// 1 = array face
										// 2 = ER projector
										// bit 7 - pitch steering (1=enabled, 0=disabled)
	BYTE		projector_beam_width;	// along track transmit beam width (degrees * 10)
	WORD  		beam_width_num;   		// cross track receive beam width numerator
	WORD 		beam_width_denom;	 	// cross track receive beam width denominator
										// beam width degrees = numerator / denominator
	short		projector_angle;		// projector pitch steering angle (degrees * 100)
	WORD		min_range;				// sonar filter settings
	WORD		max_range;
	WORD		min_depth;
	WORD		max_depth;
	BYTE		filters_active;			// range/depth filters active 
										// bit 0 - range filter (0 = off, 1 = active)
										// bit 1 - depth filter (0 = off, 1 = active)
	BYTE		spare[3];				// spare field for future growth
	short		temperature;			// temperature at sonar head (deg C * 10)
	WORD		beam_count;       		// number of sets of beam data in packet
	WORD 		range ;			 		// range for beam where n = Beam Count
										// range units = sample cells * 4
//	BYTE  		quality[cnt];   		// packed quality array (two 4 bit values/char)
										// cnt = n/2 if beam count even, n/2+1 if odd
										// cnt then rounded up to next even number
										// e.g. if beam count=101, cnt=52 
										// unused trailing quality values set to zero
										// bit 0 - brightness test (0=failed, 1=passed)
										// bit 1 - colinearity test (0=failed, 1=passed)
										// bit 2 - amplitude bottom detect used
										// bit 3 - phase bottom detect used
										// bottom detect can be amplitude, phase or both
//	WORD 		checksum;         		// checksum for data packet
};


// ID = 0x18
struct 	RI_THETA_DATA
{
	BYTE		synch_header[4];		// synch header {0xff, 0xff, 0x00, 0x00
   	BYTE      	packet_type;      		// identifier for packet type (0x18)
	BYTE		packet_subtype;		   	// identifier for packet subtype
										// for dual head system, most significant bit (bit 7)
										// indicates which sonar head to associate with packet
										//	head 1 - bit 7 set to 0
										// 	head 2 -	bit 7 set to 1 		
	WORD		latency;          		// time from ping to output (milliseconds)
	DATA_TIME	data_time;        		// time of ping for data packet
	DWORD		ping_number;			// sequential ping number from sonar startup/reset
	DWORD		sonar_id;				// least significant four bytes of Ethernet address
	WORD		sonar_model;			// coded model number of sonar
	WORD		frequency;				// sonar frequency in KHz
	WORD 		velocity;         		// programmed sound velocity (LSB = 1 m/sec)
   	WORD 		sample_rate;      		// A/D sample rate (samples per second)
	WORD 		ping_rate;        		// Ping rate (pings per second * 1000)
   	WORD 		range_set;        		// range setting for SeaBat (meters )
   	WORD 		power;            		// power setting for SeaBat  	
										// bits	0-4 -	power (0 - 8)
	WORD 		gain;             		// gain setting for SeaBat
										// bits	0-6 -	gain (1 - 45)
										// bit 	14	(0 = fixed, 1 = tvg)
										// bit	15	(0 = manual, 1 = auto)
	WORD  		pulse_width;      		// transmit pulse width (microseconds)
	BYTE		tvg_spread;				// spreading coefficient for tvg * 4 
										// valid values = 0 to 240 (0.0 to 60.0 in 0.25 steps)
	BYTE		tvg_absorp;				// absorption coefficient for tvg
	BYTE     	projector_type;      	// bits 0-4 = projector type
										// 0 = stick projector
										// 1 = array face
										// 2 = ER projector
										// bit 7 - pitch steering (1=enabled, 0=disabled)
	BYTE		projector_beam_width;	// along track transmit beam width (degrees * 10)
	WORD  		beam_width_num;   		// cross track receive beam width numerator
	WORD 		beam_width_denom;	 	// cross track receive beam width denominator
										// beam width degrees = numerator / denominator
	short		projector_angle;		// projector pitch steering angle (degrees * 100)
	WORD		min_range;				// sonar filter settings
	WORD		max_range;
	WORD		min_depth;
	WORD		max_depth;
	BYTE		filters_active;			// range/depth filters active 
										// bit 0 - range filter (0 = off, 1 = active)
										// bit 1 - depth filter (0 = off, 1 = active)
	BYTE		spare[3];				// spare field for future growth
	short		temperature;			// temperature at sonar head (deg C * 10)
	WORD		beam_count;       		// number of sets of beam data in packet
	WORD 		range; 					// [n] range for beam where n = Beam Count
										// range units = sample cells * 4
//	BYTE  		quality[cnt];   		// packed quality array (two 4 bit values/char)
										// cnt = n/2 if beam count even, n/2+1 if odd
										// cnt then rounded up to next even number
										// e.g. if beam count=101, cnt=52 
										// unused trailing quality values set to zero
										// bit 0 - brightness test (0=failed, 1=passed)
										// bit 1 - colinearity test (0=failed, 1=passed)
										// bit 2 - amplitude bottom detect used
										// bit 3 - phase bottom detect used
										// bottom detect can be amplitude, phase or both
//	WORD		intensity[n];   		// intensities at bottom detect * 8
//	WORD 		checksum;         		// checksum for data packet
};

struct	SIDESCAN_IMAGE
{
	BYTE		STX ;			// start character (0x02)
	BYTE		id ;			// packet id (0x48)
	WORD		packet_size ;	// size of packet - next field through last Amplitude value
	DWORD		ping_no ;		// sequential ping number since sonar power-up / reset
	DATA_TIME	data_time ;		// time of ping for data packet
	WORD		total_samples ;	// total number of amplitude samples for ping
	WORD		ping_packet ;	// sequence number - (0 to n )
	WORD 		velocity ;		// programmed sound velocity (LSB = 1 m/sec)
	WORD 		sample_rate ;	// A/D sample rate (samples per second)
	WORD 		ping_rate ;		// Ping rate (pings per second * 1000)
   	WORD 		range_set ;		// range setting for SeaBat (meters)
   	WORD 		power ;			// power setting for SeaBat  	
									// bits	0-4 -	power (0 - 8)
	WORD 		gain ;			// gain setting for SeaBat
									// bits	0-6 -	gain (1 - 45)
									// bit 	14	(0 = fixed, 1 = tvg)
									// bit	15	(0 = manual, 1 = auto)
	BYTE  		pulse_width ;	// transmit pulse width (microseconds)
	BYTE		tvg_spread ;	// spreading coefficient for tvg * 4 
									// valid values = 0 to 240 (0.0 to 60.0 in 0.25 steps)
	BYTE		tvg_absorp ;	// absorption coefficient for tvg
	BYTE		spare0 ;		// spare data fields for future use
	WORD		spare1[2] ;		// more spares
	short		projector ;		// projector setting 
	WORD		sample_count ;	// number of amplitude samples in packet
	WORD		amplitude ;		// amplitude data where n = sample_count
									// 12 bit amplitude stored in 12 most significant bits
//	BYTE		spare2 ;		// spare to align ETX & checksum
//	BYTE		ETX ;			// packet end character (0x03)
//	WORD		checksum ;		// checksum for data packet
};


