Eye4Software Hydromagic

  Hydrographic Survey Software

Download free demo version

Bin files used to store echo returns (water column data)

Bin files are used to store large quantities of data along the raw data file without slowing down file reading and writing progress. Because this information would take a lot of diskspace when encoded in ASCII, it is written along with RAW data files. When the first raw data file of the project (RAW0001) contains return envelope data, this is written to a file named BIN0001, and is stored in the same raw data folder.

Raw data folder containing return envelope files
Raw data folder containing return envelope files

Bin file layout

The data is stored in the raw data in three parts, each record starts with a "BinObjectHeader", followed by a "WaterColumnHeader" followed by the sample data. Sample data is encoded as unsigned shorts (unsigned 16 bit values) in MSB byte order. The "BinObject" header is 24 bytes in length and contains information on the data that is to follow. At this moment BIN files are used only to store water column data, but this header allows for future extensions of the file format.

#pragma pack( push, 1 )
typedef struct
	unsigned short		m_nMask;				// Contains a bitmask describing the items in the following data
	unsigned int		m_nReserved;				// Reserved for future use
	double			m_dblTimeStamp;				// Timestamp in seconds since 1 Jan 1970
	double			m_dblLatency;				// Latency value in seconds
	unsigned int		m_nDataSize;				// Number of bytes to follow
#pragma pack( pop)
Each BinObjectHeader structures is followed by "m_nDataSize" bytes.

When water column data is stored, the m_nMask member of the struct is set to "1". Other values are invalid at this moment. The m_dblTimeStamp member contains a timestamp in seconds since 1-Jan-1970 (Unix Epoch). Since it is a floating point number, it always contains the number of milliseconds elapsed.

The struct members are encoded in LSB byte order so no conversion is needed when reading the files on a PC. The m_nDataSize member contains the number of bytes that follows until you reach the next BinObjectHeader, thus this count includes the WaterColumnHeader size as well as the water column data itself.

#pragma pack( push, 1 )
typedef struct
	char			m_szHeader[ 8 ];			// base +  0
	unsigned __int32	m_nPingNumber;				// base +  8
	unsigned __int16	m_nReserved1;				// base + 12
	unsigned __int32	m_nReserved2;				// base + 14
	unsigned __int32	m_nDepth;				// base + 18
	unsigned __int16	m_nDraft;				// base + 22
	unsigned __int16	m_nIndexOffset;				// base + 24
	unsigned __int32	m_nGateHi;				// base + 26
	unsigned __int32	m_nGateLo;				// base + 30
	unsigned __int16	m_nScaleWidth;				// base + 34
	unsigned __int16	m_nEndOfScale;				// base + 36
		 __int16	m_nMotionStatus;			// base + 38 
		 __int16	m_nMotionHeave;
		 __int16	m_nMotionRoll;
		 __int16	m_nMotionPitch;
	unsigned __int32	m_nTideCorrection;			// base + 46	 
	unsigned __int16	m_nSampleCount;				// base + 50
	unsigned __int16	m_nSampleResolution;			// base + 52
	unsigned __int32	m_nSampleFrequency;			// base + 54
} 									// base + 58
#pragma pack( pop)
WaterColumnHeader is written once per channel per ping

WaterColumnHeader member values

The "WaterColumnHeader" structure, which is derived from ping headers used by CEE HydroSystems and Teledyne Odom, contains all information needed to interpret the water column data following this structure. Please note that the header members are encoded in MSB order, so on a PC, the bytes need to be swapped! It contains information about the number of samples, sample resolution, digitized depth, draft, scale and tide. Some struct members are not used and for future use, so we only document the members which should be used below:


The header consists out of 8 ASCII readable chars:

Byte 1-4: Source of the information. For example "#CEE": CEE Echo Sounder, "#KNG": Kongsberg Echo Sounder, "#SEG": Imported from SEG-Y, etc.
Byte    5: Reserved (comma).
Byte    6: Channel number. "1": Hi Frequency Soundings, "2": Lo Frequency Soundings.
Byte 7-8: Units used. When set to "F" feet are used. When set to "M" meters are used. When byte 7 is set to "C", it means that the scale values are in centimeters.


This struct member contains the digitized depth in centimeters when the data is in meters, or in tenths of feet when the units are set to meters.


Transducer draft used during the recording of the data. The draft is stored in centimeters when the data is in meters, or in tenths of feet when the units are set to meters.


The width in the scale (depth range) in meters, tenths of feet or centimeters when byte 7 of the m_szHeader field is set to "C". For example, when this fields has been set to 10, and the m_nEndOfScale fields is set to 25, it means that the start of the range, or minimum range value is 15. When the values of the m_nScaleWidth and m_nEndOfScale fields are equal, the minimum (scale) value is zero meter.


The maximum (scale) value (depth range) in meters, tenths of feet or centimeters when byte 7 of the m_szHeader field is set to "C". Subtract the m_nScaleWidth value to get the minimum (scale) value.


The number of echo return samples that follow this structure. For example, when the number of return samples is 1600 and the sample resolution is two bytes, the size of the data is 3200 bytes.


This field will always be set to 2 bytes, but it is recommended to check this value in case it changes in future versions, or when files are written by third-party software. When this field is set to 2, the header is followed by MSB-order encoded unsigned 16 bit values ranging from 0..65535. When a single byte is used, byte order can be ignored and the values that follow this header contain values in the range 0..255.