/**---------------------------------------------------------------------------
 ** 
 ** process.h -- 
 ** 
 ** Author          : Pierre Jaccard
 ** Created On      : 1999/07/31 21:27:44
 ** Last Modified By: Pierre Jaccard
 ** Last Modified On: 1999/08/02 08:26:10
 ** Update Count    : 22
 ** Directory       : /home/pego/pcd1/codas3c/gfi/src/apps/nbr/
 ** Version         : 0.0
 ** Status          : Unknown
 ** ---------------------------------------------------------------------- ** 
 ** DESCRIPTION: 
 ** 
 **    Undocumented.
 ** 
 ** ---------------------------------------------------------------------- ** 
 ** REVISIONS: 
 ** ---------------------------------------------------------------------- ** 
 ** CHANGES: 
 **------------------------------------------------------------------------**/


/* ##################################################################

	-Introduction:

	Header file for [[load_nbr.c]].

	The main code file [[process.c]] should include [[process_.c]], [[avg_.c]]
	and [[load_.c]], which contain utilities for processing, averaging and
	loading data, respectively.

	The following tests have been carried out:

	   +The scaling factors for velocities given in the ADCP Technical Manual and
		  defined in the list used by [[velocity_scale()]], see [[conv_nbr.h]], are
			defined for a sound speed of 1536 m/s, and use the transducer frequence
			listed in the table describing the ADCP configuration byte:

			   76.8, 152.6, 307.2, 614.4, 1228.8 kHz

		 +The velocity conversion from raw files into physical beam velocities is
		  the same, whether you use this programme or "LISTADCP". So this step
			should be correct.

		 +The velocity conversion from beam coordinate to earth coordinate is the
		  same, whether you use this programme or "LISTADCP", for the same pitch
			and roll values (of course). So, this step should also be correct. There
			is however a very little diffrence between vertical velocities. I did
			not find any error here. The error velocity is about twice as big in
			"LISTADCP", see personnal notes for an explanation.

     +Comparisons of raw data with "TRANSECT" are quite bad. But this is also
		  the case with "LISTADCP", using the same sound speed and tilt values. At
			present, RDI is trying to find an answer to this. 

		 +This programme uses the same formula as "TRANSECT" to calculate the
		  error velocity. Since this variable does not go through a rotation
			operation, these values correspond well.

		 +When comparing averaged data, the differences with "TRANSECT" are still
		  present, although much more acceptable.
	
	##################################################################
*/

#include "geninc.h"
#include "adcp.h"
#include "dbglo.h"
#include "data_id.h"
#include "ioserv.h"
#include "dbsource.h"
#include "use_db.h"
#include "vstat.h"
#include "gfimisc.h"
#include "gfinbr.h"
#include "gfinav.h"
#include "gfimath.h"

/* ##################################################################
	 -Types for Data:

	 The following structures are used to store all data specific to an
	 ensemble. In order to facilitate argument transfer between functions, they
	 are all groupped into a record.
   The [[ENSEMBLE_TYPE]] is defined in [[misc_nav.h]] and corresponds to a line
   of a [[scan_nav]] output file. In order not to be confused with ensemble
   data, it is renamed to [[SCAN_NAVLINE_TYPE]].
   
   The [[NAV_OUT_LINE_TYPE]] corresponds to a line of data read by the
   [[putnav]] programme.
   
   The [[AVG_NUM_POS_TIME_TYPE]] structure is used to keep ensemble definition
   data from different ensembles. These structures are grouped into the
   [[AVG_NPT_TYPE]], and can be filled with the [[fill_num_pos_time]] function,
   using the codes defined for this purpose (see [[avg_nbr.h]]).
   
   WARNING: the struture to store [[stop]] ensemble information is read from
            the values stored in the [[prev]] one (not the [[curr]], see the
            [[set_avg_time]] function). This is because of the construction of
						loop inside averaging intervall, which exits with the first
						ensemble of the next averaging intervall in the [[curr]] structure.
   ######################################################################## */

typedef struct
{
	FILE *lst;
	FILE *nav;
	FILE *log;
	FILE *out;
} LOAD_NBR_FILES_TYPE;

typedef struct
{
	double u;
	double v;
} DOUBLE_UV_TYPE;

typedef struct
{
	double yd;
	double filter_fraction;
	DOUBLE_LL_TYPE pos;
	DOUBLE_UV_TYPE ref;
	DOUBLE_UV_TYPE ship;
} NAV_OUT_LINE_TYPE;

typedef struct
{
	ANCILLARY_1_TYPE      anc1;
	ANCILLARY_2_TYPE      anc2;
	CONFIGURATION_1_TYPE  cnf1;
	ACCESS_VARIABLES_TYPE acc;
	BOTTOM_TRACK_TYPE     bt;
	NAVIGATION_TYPE       nav;
	UBYTE                 pf[MAX_BINS];
	DEPTH_RANGE_TYPE      dr;
} DB_ENSEMBLE_TYPE;

/* ------------------------------------------------------------------
	 Sign of Beam Vectors.

   The next structure is used to get the sign of beam vectors, according to
   the ADCP configuration flags.
	 ------------------------------------------------------------------ */
typedef struct
{
	UBYTE and_mask;   /* Mask to apply to the ADCP configuration flags    */
	UBYTE xor_mask;   /* Mask to apply to the ADCP configuration flags    */
	BYTE  sign[12];   /* Associated beam vector signs in x,y,z directions */ 
} BEAM_VECTOR_SIGN_TYPE;

/* ------------------------------------------------------------------
   The next list is an initialization for the beam vector signs for all
   possible VM-ADCP configurations.
   ------------------------------------------------------------------ */
static BEAM_VECTOR_SIGN_TYPE beam_vector_signs_list[4]=
{
	/* Concave UP */
	{ 0x0C, 0x08,   {+1, 0, -1,   -1, 0, -1,   0, +1, -1,   0, -1, -1 }}, 
	/* Concave DN */
	{ 0x0C, 0x0C,   {-1, 0, +1,   +1, 0, +1,   0, +1, +1,   0, -1, +1 }}, 
	/* Convexe UP */
	{ 0x0C, 0x00,   {-1, 0, -1,   +1, 0, -1,   0, -1, -1,   0, +1, -1 }}, 
	/* Convexe DN */ 
	{ 0x0C, 0x04,   {+1, 0, +1,   -1, 0, +1,   0, -1, +1,   0, +1, +1 }}
};

/* ------------------------------------------------------------------
	 --Process Control Structure:
	 ------------------------------------------------------------------ */

typedef struct
{
	int avg_time;                   /* Averaging time interval            */
	int max_gap;                    /* Max averaging time gap             */
	int avg_min;                    /* Minimum averaging time interval    */
	int min_bs;                     /* Minimum beam solution              */
	int max_bs;                     /* Maximum beam solution              */
	ULONG check_meth;               /* Check beams method                 */
	int check_op;                   /* Check beams operator               */
	double ba;                      /* Beam angle                         */
	double bo;                      /* Beam #3 offset                     */
	UBYTE *adcp_config;             /* Pointer to ADCP configuration byte */
	BEAM_VECTOR_SIGN_TYPE *bvsl;    /* Pointer to beam vector sign list   */
	double tr_depth;                /* Transducer depth                   */
	UBYTE  bt_pings;                /* Number of bottom profiling pings   */
	DOUBLE tr_freq;                 /* Transducer frequency               */
	int    *bml;                    /* Bin mapping variable list          */
} PROCESS_CONTROL_TYPE;

/* ------------------------------------------------------------------
	 --Record Structure:
	 ------------------------------------------------------------------ */

typedef struct
{
	DATA_FILE_INFO_TYPE   fi;
	NBR_ENSEMBLE_TYPE     ens;
	SCAN_NAV_LINE_TYPE    nav;
	NAV_OUT_LINE_TYPE     out;
	DB_ENSEMBLE_TYPE      db;
	NBR_CNV_CONTROL_TYPE *cnv;
	PROCESS_CONTROL_TYPE *cnt;
	UNISTAT_LIST_TYPE    *stat_list;
	FLAG_LIST_TYPE       *flag_list;
} LOAD_NBR_TYPE;
	 
/* ##################################################################
	 -Global Variables:
	 ################################################################## */
static int year_base;
static FILE_NAME_TYPE file_list, log_file, prdfile, dbname;

/* ------------------------------------------------------------------
	 --Other Global Variables:
	 ------------------------------------------------------------------ */

static PROCESS_CONTROL_TYPE proc_cnt;
static NBR_CNV_CONTROL_TYPE conv_cnt;
static double adcp_to_ship[3][3];
static TRANSDUCER_MISALIGNMENT_TYPE tr_mis;
static FILE_NAME_TYPE  nav_out_file;
static LOAD_NBR_TYPE ref_rec;

/* ########################################################################
   -PARAMETERS:
   ######################################################################## */

static PARAMETER_LIST_ENTRY_TYPE load_params[]=
{
	{" year_base:",       "%d",   (char *) &year_base,            TYPE_INT},
	{" file_list:",       "%79s", (char *) file_list,             TYPE_STRING},
	{" log_file:",        "%79s", (char *) log_file,              TYPE_STRING},
	{" db_name:",         "%s",   (char *) dbname,                TYPE_STRING},
	{" prd_file:",        "%79s", (char *) prdfile,               TYPE_STRING},
	{" avg_time:",        "%d",   (char *) &(proc_cnt.avg_time),  TYPE_INT},
	{NULL, NULL, (char *) NULL, 0}
};

/* ########################################################################
   -OPTIONS:
   
   Options are stored as flaggs in the [[option_bits]] bits. The meaning of
   each bit is the following:
   
      USE SCAN_NAV OUPUT: 
      
         BIT  0  :  use scan_nav output
         BIT  1  :  correct time
         BIT  2  :  correct heading
         BIT  3  :  correct pitch
         BIT  4  :  correct roll
         BIT  5  :  position & time at start
         BIT  6  :  position & time at end
         
      NAVIGATION OUTPUT:
      
         BIT  8  :  nav_output

      LOAD CONTROLS:

			   BIT 12  :  new block for each time range

      MISCELLANEOUS:
      
         BIT 24  :  bin_mapping

   ######################################################################## */

#define USE_SCAN_NAV_CODE           0  
#define CORRECT_TIME_CODE           1
#define CORRECT_HEADING_CODE        2
#define CORRECT_PITCH_CODE          3
#define CORRECT_ROLL_CODE           4
#define POS_TIME_START_CODE         5
#define POS_TIME_STOP_CODE          6

#define NAV_OUTPUT_CODE             8

#define NEW_BLOCK_EACH_TRNG_CODE   12

#define BIN_MAPPING_CODE           24

#define USE_SCAN_NAV_BIT        ((ULONG) to_bit(USE_SCAN_NAV_CODE))
#define CORRECT_TIME_BIT        ((ULONG) to_bit(CORRECT_TIME_CODE))
#define CORRECT_HEADING_BIT     ((ULONG) to_bit(CORRECT_HEADING_CODE))
#define CORRECT_PITCH_BIT       ((ULONG) to_bit(CORRECT_PITCH_CODE))
#define CORRECT_ROLL_BIT        ((ULONG) to_bit(CORRECT_ROLL_CODE))

#define NAV_OUTPUT_BIT          ((ULONG) to_bit(NAV_OUTPUT_CODE))
#define POS_TIME_START_BIT      ((ULONG) to_bit(POS_TIME_START_CODE))
#define POS_TIME_MEAN_BIT       ((ULONG) to_bit(POS_TIME_MEAN_CODE))
#define POS_TIME_STOP_BIT       ((ULONG) to_bit(POS_TIME_STOP_CODE))

#define NEW_BLOCK_EACH_TRNG_BIT ((ULONG) to_bit(NEW_BLOCK_EACH_TRNG_CODE))
#define BIN_MAPPING_BIT         ((ULONG) to_bit(BIN_MAPPING_CODE))

#define DEF_CHECK_BEAMS_METH       (BIT1)
#define DEF_CHECK_BEAMS_OP         0
#define MIN_BEAM_SOLUTION_NUM      2
#define MAX_BEAM_SOLUTION_NUM      4

static ULONG option_bits=0;

static FILE_NAME_TYPE scan_nav_file;
static char pos_time_ref_str[50];

static OPTION_TYPE use_scan_nav_opts[]=
{
	{"end", 0, NULL, (char *) NULL},
	{"file:",      TYPE_STRING,          op_get_param, (char *) scan_nav_file},
	{"time",       CORRECT_TIME_CODE,    set_long_bit, (char *) &option_bits},
	{"heading",    CORRECT_HEADING_CODE, set_long_bit, (char *) &option_bits},
	{"pitch",      CORRECT_PITCH_CODE,   set_long_bit, (char *) &option_bits},
	{"roll",       CORRECT_ROLL_CODE,    set_long_bit, (char *) &option_bits},
	{"time_ref:",  TYPE_STRING,          op_get_param, 
	 (char *) pos_time_ref_str},
	{NULL, 0, NULL, (char *) NULL}
};

static OPTION_TYPE time_control_opts[]=
{
	{"end", 0, NULL, (char *) NULL},
	{"max_gap=", TYPE_INT, op_get_param, (char *) &(proc_cnt.max_gap)},
	{"avg_min=", TYPE_INT, op_get_param, (char *) &(proc_cnt.avg_min)},
	{NULL, 0, NULL, (char *) NULL}
};


static OPTION_TYPE tr_mis_opts[]=
{
	{"end", 0, NULL, (char *) NULL},
	{"heading=", TYPE_DOUBLE, op_get_param, (char *) &(tr_mis.heading)},
	{"pitch=",   TYPE_DOUBLE, op_get_param, (char *) &(tr_mis.pitch)},
	{"roll=",    TYPE_DOUBLE, op_get_param, (char *) &(tr_mis.roll)},
	{NULL, 0, NULL, (char *) NULL}
};


static OPTION_TYPE nav_output_opts[]=
{
	{"end", 0, NULL, (char *) NULL},
	{"file:", TYPE_STRING, op_get_param, (char *) nav_out_file},
	{NULL, 0, NULL, (char *) NULL}
};


OPTION_TYPE solution_controls_opts[]=
{
	{"end", 0, NULL, (char *) NULL},
	{"min_beam=", TYPE_INT,  op_get_param, (char *) &(proc_cnt.min_bs)},
	{"max_beam=", TYPE_INT,  op_get_param, (char *) &(proc_cnt.max_bs)},
  /* 1999/08/02 Pierre Jaccard
        Comented out next lines, as methods are currently hard coded
	{"methods=",  TYPE_LONG, op_get_param, (char *) &(proc_cnt.check_meth)},
	{"operator=", TYPE_CHAR, op_get_param, (char *) &(proc_cnt.check_op)},
  */
	{NULL, 0, NULL, (char *) NULL}
};


static OPTION_TYPE transducer_opts[]=
{
	{"end", 0, NULL, (char *) NULL},
	{"beam_angle=",              TYPE_DOUBLE, op_get_param, 
	 (char *) &(proc_cnt.ba)},
	{"beam_3_offset:",           TYPE_DOUBLE, op_get_param, 
	 (char *) &(proc_cnt.bo)},
	{"transducer_depth:",        TYPE_DOUBLE, op_get_param, 
	 (char *) &(proc_cnt.tr_depth)},
	{"transducer_frequency:",    TYPE_DOUBLE, op_get_param, 
	 (char *) &(proc_cnt.tr_freq)},
	{"transducer_misalignment:",           1, execute_sub_options, 
	 (char *) tr_mis_opts},
	{"bt_profiling_pings:",      TYPE_INT, op_get_param, 
	 (char *) &(proc_cnt.bt_pings)},
	{NULL, 0, NULL, (char *) NULL}
};	

static OPTION_TYPE cnv_control_opts[]=
{
	{"end", 0, NULL, (char *) NULL},
	{"bin_mapping",    BIN_MAPPING_CODE, set_long_bit,        
	 (char *) &option_bits},
	{"echo_scale_temp:",    TYPE_DOUBLE, op_get_param, 
	 (char *) &(conv_cnt.echo_scale_temp)},
	{"sound_speed:",        TYPE_DOUBLE, op_get_param, 
	 (char *) &(conv_cnt.sound_speed)},
	{"sound_absorption:",   TYPE_DOUBLE, op_get_param, 
	 (char *) &(conv_cnt.sound_abs)},
	{NULL, 0, NULL, (char *) NULL}
};	

static OPTION_TYPE proc_control_opts[]=
{
	{"end", 0, NULL, (char *) NULL},
	{"beam_solutions:",               1, execute_sub_options,
	 (char *) solution_controls_opts},
	{"time_controls:",                1, execute_sub_options,
	 (char *) time_control_opts},
	{"new_block", NEW_BLOCK_EACH_TRNG_CODE, set_long_bit,
	 (char *) &option_bits},
	{NULL, 0, NULL, (char *) NULL}
};

/* ------------------------------------------------------------------
	 --Main Option List:
	 ------------------------------------------------------------------ */

static OPTION_TYPE load_options[]=
{
	{"end", 0, NULL, (char *) NULL},
	{"OPTIONS:", 0, NULL, (char *) NULL},
	{"use_scan_nav:",              1, execute_sub_options, 
	 (char *) use_scan_nav_opts},
	{"nav_output:",                1, execute_sub_options, 
	 (char *) nav_output_opts},
	{"conversion_controls:",       1, execute_sub_options, 
	 (char *) cnv_control_opts},
	{"transducer_settings:",       1, execute_sub_options,
	 (char *) transducer_opts},
	{"processing_controls:",       1, execute_sub_options,
	 (char *) proc_control_opts},
	{NULL, 0, NULL, (char *) NULL}
};

/* ##################################################################
   -Flag List:
   
   The [[AVERAGE_FLAG]] is used to define if current data should be averaged or
   not. It can take the following values (definition are available in
	 [[avg_nbr.h]]):
   
   	0  :  the flag is not set
   	
   	positive values: average should be carried out
   	
   		1  :  this corresponds to a normal situation, where the end of the 
   				  averaging interval has been reached
   		2  :  this is when there is a too big time gap since previous
   		      ensemble, however data being averaged until previous ensemble
   		      may still be used to form an ensemble.
   		3  :  this is similar to the previous case, but it occurs when an end
   		      of file has been reached.
   		      
   	negative valuse: average should not be carried out 
   	
   		-1  : this occurs when there is a too long time gap since previous
   		      ensemble, and that data being currently averaged are not worth
   		      to form an ensemble.
   ------------------------------------------------------------------ */

#define AVERAGE_FLAG          -1
#define BEAM_SOLUTION_FLAG    -2
#define LOAD_BLOCK_VAR_FLAG    1
#define LOAD_PROF_VAR_FLAG     2

FLAG_LIST_TYPE flag_list[]=
{
	{"average",         1,        NULL, AVERAGE_FLAG},
	{"beam_solution",   MAX_BINS, NULL, BEAM_SOLUTION_FLAG},
	{"load_block_var",  1,        NULL, LOAD_BLOCK_VAR_FLAG},
	{"load_prof_var",   1,        NULL, LOAD_PROF_VAR_FLAG},
	{NULL, 0, NULL, 0}
};

/* ------------------------------------------------------------------
	-Conversion List:
	
	The following list defines the variables that can be converted from the NB
	ADCP raw format into their physical scales. The [[NBR_CONVERSION_TYPE]]
	structure is defined in [[conv_nbr.h]]. The value of [[name_code]] should be
	the same as the one defined in the [[NBR_SCALING_TYPE]] list, so that
	factors and offsets for the conversion can be retrieved from the
	[[nbr_scaling_list]].
	
	In order to initialize the data location (i.e. the value of the [[data]]
	pointer), a temporary record is declared here. Data will have to be copied
	into this record before applying the conversion. Since converted data are
	stored in an [[UNISTAT_LIST_TYPE]] list, pointed by the [[stat_list]]
	pointer, the value of the latter will also be copied into the temporary
	record corresponding [[stat_list]] pointer. Hence, backward copy is not
	required.  
	------------------------------------------------------------------ */

/* 98/09/07 PJ
	          Modified PERCENT_GOOD from BYTE to UBYTE and SPECTRAL_WIDTH
						related data from UBYTE to BYTE in conversion list below. */
 
NBR_CONVERSION_TYPE nbr_conversion_list[]=
{
	{"nbr_heading",                  CNV_NBR_HEADING_CODE,        
	 USHORT_VALUE_CODE,	(char *) &(ref_rec.ens.leader.heading)},							
	{"nbr_heading_sdev",             CNV_NBR_HEADING_SDEV_CODE,
	 UBYTE_VALUE_CODE, 	(char *) &(ref_rec.ens.leader.heading_std_dev)},
	{"nbr_pitch", 							CNV_NBR_PITCH_CODE,
	 SHORT_VALUE_CODE,		(char *) &(ref_rec.ens.leader.pitch_tilt)},
	{"nbr_pitch_sdev",               CNV_NBR_PITCH_SDEV_CODE,
	 UBYTE_VALUE_CODE,		(char *) &(ref_rec.ens.leader.pitch_std_dev)},
	{"nbr_roll", 						   CNV_NBR_ROLL_CODE,
	 SHORT_VALUE_CODE,		(char *) &(ref_rec.ens.leader.roll_tilt)},
	{"nbr_roll_sdev",                CNV_NBR_ROLL_SDEV_CODE,
	 UBYTE_VALUE_CODE,		(char *) &(ref_rec.ens.leader.roll_std_dev)},
	{"nav_heading", 						CNV_NAV_HEADING_CODE,
	 DOUBLE_VALUE_CODE,	(char *) &(ref_rec.nav.prh.heading.mean)},
	{"nav_heading_sdev",             CNV_NAV_HEADING_SDEV_CODE,
	 DOUBLE_VALUE_CODE,	(char *) &(ref_rec.nav.prh.heading.sdev)},
	{"nav_pitch", 							CNV_NAV_PITCH_CODE,
	 DOUBLE_VALUE_CODE,	(char *) &(ref_rec.nav.prh.pitch.mean)},
	{"nav_pitch_sdev",               CNV_NAV_PITCH_SDEV_CODE,
	 DOUBLE_VALUE_CODE,	(char *) &(ref_rec.nav.prh.pitch.sdev)},
	{"nav_roll", 						   CNV_NAV_ROLL_CODE,
	 DOUBLE_VALUE_CODE,	(char *) &(ref_rec.nav.prh.roll.mean)},
	{"nav_roll_sdev",                CNV_NAV_ROLL_SDEV_CODE,
	 DOUBLE_VALUE_CODE,	(char *) &(ref_rec.nav.prh.roll.sdev)},
	{"adcp_temperature",             CNV_ADCP_TEMP_CODE,
	 USHORT_VALUE_CODE,	(char *) &(ref_rec.ens.leader.adcp_temp)},
	{"ctd_conductivity",             CNV_CTD_COND_CODE,
	 ULONG_VALUE_CODE,		(char *) &(ref_rec.ens.ctd_conductivity_count)},
	{"ctd_temperature",              CNV_CTD_TEMP_CODE,
	 ULONG_VALUE_CODE,		(char *) &(ref_rec.ens.ctd_temperature_count)},
	{"ctd_depth",                    CNV_CTD_DEPTH_CODE,
	 ULONG_VALUE_CODE,		(char *) &(ref_rec.ens.ctd_depth_count)},
	{"bottom_track_velocity",        CNV_BT_VELOCITY_CODE,
	 SHORT_VALUE_CODE,		(char *) ref_rec.ens.bottom_track_velocity},
	{"bottom_track_range",           CNV_BT_RANGE_CODE,
	 USHORT_VALUE_CODE,	  (char *) ref_rec.ens.leader.bottom_track_range},
	{"bottom_track_percent_good",    CNV_BT_PCG_CODE,
	 UBYTE_VALUE_CODE,		(char *) ref_rec.ens.bottom_track_percent_good},
	{"velocity",                     CNV_VELOCITY_CODE,
	 SHORT_VALUE_CODE,		(char *) ref_rec.ens.velocity},
	{"raw_echo_intensity",           CNV_RAW_ECHO_CODE,
	 UBYTE_VALUE_CODE,		(char *) ref_rec.ens.echo_intensity},
	{"spectral_width",               CNV_SPECTRAL_WIDTH_CODE,
	 UBYTE_VALUE_CODE,		(char *) ref_rec.ens.spectral_width},
	{"percent_good",                 CNV_PERCENT_GOOD_CODE,
	 UBYTE_VALUE_CODE,		(char *) ref_rec.ens.percent_good},
	{"raw_spectral_width",           CNV_RAW_SPEC_WIDTH_CODE,
	 UBYTE_VALUE_CODE,		(char *) ref_rec.ens.spectral_width},
	{ NULL, -1, -1, (char *) NULL}
};

/* ------------------------------------------------------------------
   -Unistat List:
   
   Data to be averaged are stored into an [[UNISTAT_LIST_TYPE]]. The next list
   defines the variables to be averaged. Variables with negative codes will
   not be loaded into the data base.  
	 ------------------------------------------------------------------ */

#define HEADING_CODE					0
#define HEADING_SDEV_CODE			1
#define ADCP_TEMP_CODE				2
#define CTD_COND_CODE				  3
#define CTD_TEMP_CODE				  4
#define CTD_DEPTH_CODE				5
#define BT_VELOCITY_CODE			6
#define BT_RANGE_CODE				  7
#define BT_PCG_CODE					  8
#define VELOCITY_CODE				  9
#define RAW_ECHO_CODE				 10
#define SPEC_WIDTH_CODE      11
#define PCG_CODE             12
#define SHIP_U_CODE          13
#define SHIP_V_CODE          14
#define SHIP_LON_CODE        15
#define SHIP_LAT_CODE        16
#define PITCH_CODE				   17
#define PITCH_SDEV_CODE			 18
#define ROLL_CODE					   19
#define ROLL_SDEV_CODE			 20
#define AMPLITUDE_CODE       21  /* Non-range normalized echo amplitude */
#define RN_AMPLITUDE_CODE    22  /* Range normalized echo amplitude     */
#define RAW_MEAN_AMP_CODE    23
#define MEAN_PCG_CODE        24
#define RAW_SPEC_WIDTH_CODE  25
#define MEAN_SPEC_WIDTH_CODE 26
#define BEAM_SOL_CODE        -VELOCITY_CODE
#define BT_BEAM_SOL_CODE     -BT_VELOCITY_CODE
#define LAST_GOOD_BIN_CODE   -100

UNISTAT_LIST_TYPE avg_nbr_stat_list[]=
{
	{"heading", 							    "%8.2lf", 1,        U_ALL, 
	 HEADING_CODE,      NULL, NULL},
	{"heading_sdev",              "%8.2lf", 1,        U_ALL, 
	 HEADING_SDEV_CODE, NULL, NULL},
	{"pitch", 							      "%8.2lf", 1,        U_ALL, 
	 PITCH_CODE,        NULL, NULL},
	{"pitch_sdev",                "%8.2lf", 1,        U_ALL, 
	 PITCH_SDEV_CODE,   NULL, NULL},
	{"roll", 						   	      "%8.2lf", 1,        U_ALL, 
	 ROLL_CODE,         NULL, NULL},
	{"roll_sdev",                 "%8.2lf", 1,        U_ALL, 
	 ROLL_SDEV_CODE,    NULL, NULL},
	{"adcp_temperature",          "%8.2lf", 1,        U_ALL, 
	 ADCP_TEMP_CODE,    NULL, NULL},
	{"ctd_conductivity",          "%8.2lf", 1,        U_ALL, 
	 CTD_COND_CODE,     NULL, NULL},
	{"ctd_temperature",           "%8.2lf", 1,        U_ALL, 
	 CTD_TEMP_CODE,     NULL, NULL},
	{"ctd_depth",                 "%8.2lf", 1,        U_ALL, 
	 CTD_DEPTH_CODE,      NULL, NULL},
	{"bottom_track_velocity",     "%8.2lf", 4,        U_ALL, 
	 BT_VELOCITY_CODE,    NULL, NULL},
	{"bottom_track_range",        "%8.2lf", 4,        U_ALL, 
	 BT_RANGE_CODE,       NULL, NULL},
	{"bottom_track_percent_good", "%8.2lf", 4,        U_ALL, 
	 BT_PCG_CODE,         NULL, NULL},
	{"velocity",                  "%8.2lf", 4*MAX_BINS, U_ALL, 
	 VELOCITY_CODE,       NULL, NULL},
	{"raw_echo_intensity",        "%8.2lf", 4*MAX_BINS, U_ALL, 
	 RAW_ECHO_CODE,       NULL, NULL},
	{"raw_spectral_width",        "%8.2lf", 4*MAX_BINS, U_ALL, 
	 RAW_SPEC_WIDTH_CODE, NULL, NULL},
	{"spectral_width",            "%8.2lf", 4*MAX_BINS, U_ALL, 
	 SPEC_WIDTH_CODE, NULL, NULL},
	{"percent_good",              "%8.2lf", 4*MAX_BINS, U_ALL, 
	 PCG_CODE,            NULL, NULL},
	 /* ---------------------------------
			Variable generated during processing:
			--------------------------------- */
	{"mean_pcg",                  "%8.2lf", MAX_BINS,   U_ALL, 
		MEAN_PCG_CODE,       NULL, NULL},
	{"raw_mean_amp",               "%8.2lf", MAX_BINS,   U_ALL,
	  RAW_MEAN_AMP_CODE,   NULL, NULL},
	{"mean_spectral_width",        "%8.2lf", MAX_BINS,   U_ALL, 
	  MEAN_SPEC_WIDTH_CODE, NULL, NULL},
	/* -------------------------------------
	   Variable used for processing controls
		 ------------------------------------- */
	 {"beam_solution",             "%8.2lf", 4,          U_ALL, 
		BEAM_SOL_CODE,       NULL, NULL},
	 {"bt_beam_solution",          "%8.2lf", 4,          U_ALL, 
		BT_BEAM_SOL_CODE,    NULL, NULL},
	 {"last_good_bin",             "%8.2lf", 1,          U_ALL, 
		LAST_GOOD_BIN_CODE,  NULL, NULL},
	{ NULL, NULL, 0, 0, 0, NULL, NULL }
};

/* ------------------------------------------------------------------
	 --Bin Mapping List:

	 Below is a list of the variables above that should be bin mapped (pitch and
	 roll compensed) if the [[bin_mapping]] option ism selected.
	 ------------------------------------------------------------------ */

static int bin_map_list[]=
{
	VELOCITY_CODE,
	RAW_ECHO_CODE,
	RAW_SPEC_WIDTH_CODE,
	SPEC_WIDTH_CODE,
	PCG_CODE,
	BADINT
};

/* ------------------------------------------------------------------
   -Data vs Conversion Correspondance:
   
   The following list is used to determine the correspondance between an
   unistat variable and its corresponding variable in the conversion list. The
   value of [[uni_code]] must correspond to a code in the unistat list above.
   The value of [[cnv_code]] must correspond the variable's associated code in
   the conversion list. If this is set to BADINT, then it is assumed that the
   correspondance with the conversion list is not known at initialization.  
	 ------------------------------------------------------------------ */
  
DATA_TO_CONVERSION_TYPE uni_to_cnv_list[]=
{
	{"heading", 							       
	 HEADING_CODE, 				BADINT},
	{"heading_sdev",                 
	 HEADING_SDEV_CODE, 	BADINT},						
	{"pitch", 							         
	 PITCH_CODE, 				  BADINT},
	{"pitch_sdev",                   
	 PITCH_SDEV_CODE, 		BADINT},						
	{"roll", 						   	         
	 ROLL_CODE, 					BADINT},
	{"roll_sdev",                    
	 ROLL_SDEV_CODE, 			BADINT},						
	{"adcp_temperature",             
	 ADCP_TEMP_CODE, 			CNV_ADCP_TEMP_CODE},
	{"ctd_conductivity",             
	 CTD_COND_CODE, 			CNV_CTD_COND_CODE},
	{"ctd_temperature",              
	 CTD_TEMP_CODE, 			CNV_CTD_TEMP_CODE},
	{"ctd_depth",                    
	 CTD_DEPTH_CODE, 			CNV_CTD_DEPTH_CODE},
	{"bottom_track_velocity",        
	 BT_VELOCITY_CODE, 	  CNV_BT_VELOCITY_CODE},
	{"bottom_track_range",           
	 BT_RANGE_CODE, 			CNV_BT_RANGE_CODE},
	{"bottom_track_percent_good",    
	 BT_PCG_CODE, 				CNV_BT_PCG_CODE},
	{"velocity",                     
	 VELOCITY_CODE, 			CNV_VELOCITY_CODE},
	{"raw_echo_intensity",               
	 RAW_ECHO_CODE,       CNV_RAW_ECHO_CODE},
	{"spectral_width",               
	 SPEC_WIDTH_CODE,     CNV_SPECTRAL_WIDTH_CODE},
	{"percent_good",                 
	 PCG_CODE, 	          CNV_PERCENT_GOOD_CODE},
	{"raw_spectral_width",               
	 RAW_SPEC_WIDTH_CODE, CNV_RAW_SPEC_WIDTH_CODE},
	{ NULL, -1, -1}
};

/* ------------------------------------------------------------------
   The following list initializes conversion parameters for the variables
   codes defined above. Bad values implies that conversion is unknown at
   initialization time. This is for example the case for velocities, whose
   conversion parameters depend on the ADCP configuration flags.
   ------------------------------------------------------------------ */
static NBR_SCALING_TYPE nbr_scaling_list[]=
{
	{"nbr_heading",                  CNV_NBR_HEADING_CODE,			
	 BADDOUBLE,     BADDOUBLE},	
	{"nbr_heading_sdev",             CNV_NBR_HEADING_SDEV_CODE,
	 1.0, 					0.0},
	{"nbr_pitch", 							     CNV_NBR_PITCH_CODE,
	 BADDOUBLE,     BADDOUBLE},
	{"nbr_pitch_sdev",               CNV_NBR_PITCH_SDEV_CODE,
	 0.1,           0.0},
	{"nbr_roll", 						         CNV_NBR_ROLL_CODE,
	 BADDOUBLE,     BADDOUBLE},
	{"nbr_roll_sdev",                CNV_NBR_ROLL_SDEV_CODE,
	 0.1, 					0.0},
	{"nav_heading", 						     CNV_NAV_HEADING_CODE,
	 1.0,						0.0},
	{"nav_heading_sdev",             CNV_NAV_HEADING_SDEV_CODE,
	 1.0,						0.0},
	{"nav_pitch", 							     CNV_NAV_PITCH_CODE,
	 1.0,						0.0},		
	{"nav_pitch_sdev",               CNV_NAV_PITCH_SDEV_CODE,
	 1.0,						0.0},
	{"nav_roll", 						         CNV_NAV_ROLL_CODE,
	 1.0,						0.0},
	{"nav_roll_sdev",                CNV_NAV_ROLL_SDEV_CODE,
	 1.0,						0.0},
	{"adcp_temperature",             CNV_ADCP_TEMP_CODE,
	 -50.0/4096.0,       45.0},
	{"ctd_conductivity",             CNV_CTD_COND_CODE,
	 1.0,  					0.0},
	{"ctd_temperature",              CNV_CTD_TEMP_CODE,
	 1.0,  					0.0},	
	{"ctd_depth",                    CNV_CTD_DEPTH_CODE,
	 1.0,  					0.0},
	{"bottom_track_velocity",        CNV_BT_VELOCITY_CODE,
	 BADDOUBLE,			BADDOUBLE},
	{"bottom_track_range",           CNV_BT_RANGE_CODE,
	 1.0,						0.0},
	{"bottom_track_percent_good",    CNV_BT_PCG_CODE,
	 1.0,						0.0},
	{"velocity",                     CNV_VELOCITY_CODE,
	 BADDOUBLE,			BADDOUBLE},
	{"echo_intensity",               CNV_ECHO_INTENSITY_CODE,
	 BADDOUBLE,			BADDOUBLE},
	{"raw_echo_intensity",           CNV_RAW_ECHO_CODE,
	 1.0,			      0.0},
	{"spectral_width",               CNV_SPECTRAL_WIDTH_CODE,
	 BADDOUBLE,			BADDOUBLE},
	{"raw_spectral_width",           CNV_RAW_SPEC_WIDTH_CODE,
	 1.0,			      0.0},
	{"percent_good",                 CNV_PERCENT_GOOD_CODE,
	 1.0,						0.0},
	{"nav_ship_u",                   CNV_NAV_SHIP_U_CODE, 
	 1.0,  					0.0},
	{"nav_ship_v",                   CNV_NAV_SHIP_V_CODE,
	 1.0,  					0.0},
	{"nav_ship_lat",                 CNV_NAV_SHIP_LAT_CODE,
	 1.0,  					0.0},
	{"nav_ship_lon",                 CNV_NAV_SHIP_LON_CODE,
	 1.0,  					0.0},
	{NULL, 0, 0.0, 0.0}
};













