/**---------------------------------------------------------------------------
 ** 
 ** convert.h -- 
 ** 
 ** Author          : Pierre Jaccard
 ** Created On      : 1999/07/15 10:15:54
 ** Last Modified By: Pierre Jaccard
 ** Last Modified On: 1999/07/31 23:41:52
 ** Update Count    : 16
 ** Directory       : /home/pego/pcd1/codas3c/gfi/src/libs/nbr/
 ** Version         : 0.0
 ** Status          : Unknown
 ** ---------------------------------------------------------------------- ** 
 ** DESCRIPTION: 
 ** 
 **    See associated file convert.c
 **
 **    Several conversion macros are in addition provided here.
 ** 
 ** ---------------------------------------------------------------------- ** 
 ** REVISIONS: 
 ** ---------------------------------------------------------------------- ** 
 ** CHANGES: 
 **------------------------------------------------------------------------**/

#ifndef  gfilib_nbr_convert_already_included
#define  gfilib_nbr_convert_already_included

#include "geninc.h"
#include "adcp.h"
#include "gfimath.h"

/* ------------------------------------------------------------------
	Conversion Macros:

	These functions are used to convert NB raw data to their physical dimension
	and value.

	* Pitch, Roll, and Heading:

	Two kinds of PRH conversions are available: 

	+ ranging from 0 to 360,
	+ ranging from -180 to 180

	* 360 and 180 Value Ranges:

	Transform a value ranging from 0 to 360 into a value ranging from -180 to
	+180, and vice versa.
	------------------------------------------------------------------ */

/*
  Convert ADCP heading to a 0..360 degrees range 
*/
#define cnv_heading_360(x) (((double) (x))*360.0/65536.0)

/*
  Convert ADCP heading to a -180..+180 degrees range 
*/
#define cnv_heading_180(x) (to180(cnv_heading_360(x)))

/*
  Convert ADCP heading standard deviation
*/
#define cnv_heading_sdev(x) (((double) (x)) * 1.0)

/*
  Convert ADCP pitch to a 0..360 range
*/
#define cnv_pitch_360(x)	 (((double) (x))*360.0/65536.0)

/*
  Convert ADCP pitch to a -180..+180 range
*/
#define cnv_pitch_180(x) (to180(cnv_pitch_360(x)))

/*
  Convert ADCP pitch standard deviation
*/
#define cnv_pitch_sdev(x) (((double) (x)) * 0.1)

/*
  Convert ADCP roll to a 0..360 range
*/
#define cnv_roll_360(x)		 (((double) (x))*360.0/65536.0)

/*
  Convert ADCP roll to a -180..+180 range
*/
#define cnv_roll_180(x) (to180(cnv_roll_360(x)))

/*
  Convert ADCP roll standard deviation
*/
#define cnv_roll_sdev(x) (((double) (x)) * 0.1)
	
/*
  Convert ADCP temeprature into degC
*/
#define cnv_adcp_temp(x) (45.0 - (((double) (x))*50.0/4096.0))
		
/*
  Convert percent good of bottom pings
*/
#define cnv_bt_pcg(x) (((double) (x)) *100.0/15.0)
	
/*
  Convert percent good threshold
*/
#define cnv_pcg_threshold(x) (((double) (x))*1.0)

/*
  Convert signal over noise threshold
*/
#define cnv_sn_threshold(x) (((double) (x))*0.1)
	
/*
	Convert heading into ADCP value
*/
#define to_nbr_heading(x)			(round((to360(x))*(65536.0/360.0)))

/*
  Convert pitch into ADCP value
*/
#define to_nbr_pitch(x)				(round((to180(x))*(65536.0/360.0)))

/*
  Convert roll into ADCP value
*/
#define to_nbr_roll(x)				(round((to180(x))*(65536.0/360.0)))

/*
  Convert heading standrd deviation into ADCP value
*/
#define to_nbr_hdg_sdev(x)		(round((x)*(1.0)))

/*
  Convert pitch standard deviation into ADCP value
*/
#define to_nbr_pitch_sedv(x)  (round((x)*(10.0)))

/*
  Convert roll standard deviation into ADCP value
*/
#define to_nbr_roll_sedv(x)		(round((x)*(10.0)))
	
/* ------------------------------------------------------------------
	 The function returning the velocity scale needs a definition list for
	 getting the corresponding scale for a given ADCP configuration. This list
	 is defined below.
	 ------------------------------------------------------------------ */	
typedef struct
{
	UBYTE and_mask; /* Mask to apply to ADCP configuration flags */
	UBYTE xor_mask; /* Mask to apply to ADCP configuration flags */ 
	double scale;   /* Velocity scale associated to the ADCP configuration flags 
                   */ 
} NBR_VELOCITY_SCALE_TYPE;


/* ------------------------------------------------------------------
   Conversion list.
   
   The following structure is used to define which variables can be converted
   from the NB ADCP raw format. The pointer data must point to the address
   of the variable, and type_code must contain the code for the type of
   the variable.
   
   The value of code is used to identify uniquely the variable. The codes
   defined below may be used in order to make the programme more
   transparent. These codes must also correspond to those defined in the
   nbr_scaling_list defined later, so that for each variable, there is a
   factor and an offset for its scaling.
   
   This list is not initialized here, so that freedom on the location of the
   different variables is available.  
	 ------------------------------------------------------------------ */

typedef struct
{
	char *name;       /* Name of variable                  */
	int name_code;  	/* Conversion code                   */
	int type_code;		/* Code for the type of the variable */
	char *data;			  /* Pointer to the first data element */
} NBR_CONVERSION_TYPE;

#define CNV_NBR_HEADING_CODE				1
#define CNV_NBR_HEADING_SDEV_CODE		2
#define CNV_NBR_PITCH_CODE				  3
#define CNV_NBR_PITCH_SDEV_CODE			4
#define CNV_NBR_ROLL_CODE					  5
#define CNV_NBR_ROLL_SDEV_CODE			6
#define CNV_NAV_HEADING_CODE        7
#define CNV_NAV_HEADING_SDEV_CODE		8
#define CNV_NAV_PITCH_CODE				  9
#define CNV_NAV_PITCH_SDEV_CODE		 10
#define CNV_NAV_ROLL_CODE				   11
#define CNV_NAV_ROLL_SDEV_CODE		 12
#define CNV_ADCP_TEMP_CODE				 13
#define CNV_CTD_COND_CODE				   14
#define CNV_CTD_TEMP_CODE				   15
#define CNV_CTD_DEPTH_CODE				 16
#define CNV_BT_VELOCITY_CODE			 17
#define CNV_BT_RANGE_CODE				   18
#define CNV_BT_PCG_CODE					   19
#define CNV_VELOCITY_CODE				   20
#define CNV_ECHO_INTENSITY_CODE		 21
#define CNV_SPECTRAL_WIDTH_CODE    22
#define CNV_PERCENT_GOOD_CODE      23
#define CNV_NAV_SHIP_U_CODE        24
#define CNV_NAV_SHIP_V_CODE        25
#define CNV_NAV_SHIP_LON_CODE      26
#define CNV_NAV_SHIP_LAT_CODE      27
#define CNV_RAW_SPEC_WIDTH_CODE    28
#define CNV_RAW_ECHO_CODE          29

/* ------------------------------------------------------------------
   Scaling List.
   
   The following list defines the conversions to apply for the different NB
   ADCP raw variables. The conversion is carried as follows:
   
   	value = factor * count + offset
   	
   where count is the value read from the raw data files. A value of
   BADDOUBLE for the factor assumes that the conversion parameters is not
   known at initialization. Special conversion must then be applied in the main
   programme.
	 ------------------------------------------------------------------ */
typedef struct
{
	char  *name;        /* Name of variable */
	int    code;        /* Conversion code  */
	double factor;      /* Scaling factor   */
	double offset;      /* Offset parameter */
} NBR_SCALING_TYPE;


/* ------------------------------------------------------------------
   Data to Conversion Correspondance.
   
   The following structure is used to determine the correspondance between a
   variable code and its corresponding code in the conversion list. The value
   of var_code must correspond to a code in the data list to convert. The
   value of cnv_code must correspond the variable's associated code in the
   conversion list above.
   ------------------------------------------------------------------ */
typedef struct
{
	char *name;                /* Name of variable                   */
	int  var_code;             /* Code of variable in main programme */
	int  cnv_code ;            /* Associated conversion code         */
} DATA_TO_CONVERSION_TYPE;

/* ------------------------------------------------------------------
	 Conversion Control Structure.

	 The following structure is used to get access to the different variables
	 necessary to apply the conversion from NB ADCP raw data into their physical
	 format.
	 ------------------------------------------------------------------ */
typedef struct
{
	char *buff;                                /* Pointer to buffer where to
                                                look for the raw data.
                                                Addresses to data defined in the
                                                NBR_CONVERSION_TYPE list above
                                                must point into this buffer. */ 
	int  buff_size;                            /* Size of above buffer         */
	UBYTE *adcp_config;                        /* Pointer the ADCP cfg byte    */
	double echo_scale_temp;                    /* Temperature for echo
                                                scaling. Used to convert echo
                                                intensity into dB            */
	double sound_speed;                        /* Sound speed                  */
	DOUBLE sound_abs;                          /* Sound absorption coefficient */
	TRANSDUCER_MISALIGNMENT_TYPE *tr_mis;      /* Pointer to transducer
                                                misalignment                 */ 
	NBR_SCALING_TYPE *scaling_list;            /* Pointer to NBR scaling list  */
	NBR_CONVERSION_TYPE *conversion_list;      /* Pointer to conversion list   */
	DATA_TO_CONVERSION_TYPE *data_to_cnv_list; /* Pointer to data cnv list     */
} NBR_CNV_CONTROL_TYPE;     

/*
  The default speed of sound to use, in m/s.
*/
#define DEFAULT_SOUND_SPEED 1536.0


	
#if PROTOTYPE_ALLOWED

int rtc_to_ymdhms(NBR_RTC_TYPE *rtc, YMDHMS_TIME_TYPE *dbt, int year);
double rtc_to_yd(NBR_RTC_TYPE *rtc, int year);
LONG rtc_diff(NBR_RTC_TYPE *rtc1, int y1, NBR_RTC_TYPE *rtc2, int y2);
int byte_hexa_to_dec(UBYTE *dst, UBYTE *src, int n);
int byte_dec_to_hexa(UBYTE *dst, UBYTE *src, int n);
int pitch_sign(UBYTE adcp_config);
int roll_sign(UBYTE adcp_config);
double spectral_width_scale(UBYTE adcp_config);
double velocity_scale(UBYTE adcp_config);
int get_nbr_cnv_parameters(double *factor, double *offset, int code, 
													 NBR_CNV_CONTROL_TYPE *cnv_control);
int nbr_cnv_one_data(UNISTAT_LIST_TYPE *uni, int cnv_code, 
										 NBR_CNV_CONTROL_TYPE *cnv_control);
int nbr_cnv_all_data(UNISTAT_LIST_TYPE *uni_list, char *nbr_buff,
										 NBR_CNV_CONTROL_TYPE *cnv_control);

#else

int rtc_to_ymdhms(); 
double rtc_to_yd() ;
LONG rtc_diff();
int byte_hexa_to_dec();
int byte_dec_to_hexa();
int pitch_sign();
int roll_sign();
double spectral_width_scale();
double velocity_scale();
int get_nbr_cnv_parameters();
int nbr_cnv_one_data();
int nbr_cnv_all_data();

#endif

#endif /* gfilib_nbr_convert_already_included */
