/**************************************************************************
 tran_to_db_bbp.c 

  (based on trantodb.c and nbptodb.c for NB processed transect files by UH)

   Modified Sept '95
                Dave Senciall
                NWAFC,DFO,Gov of Canada

 Here are some functions for filling CODAS ADCP structures from the
   BBP structures.  Elements that are not filled in these functions must
   be initialized to BADxxx by an appropriate initialization function.

   At this point I am not making any provision for averaging processed
   ensembles; we are just making a straight transfer.  Presumably averaging
   could be done after this, with the CODAS structures as input.

****************************************************************************/

#include <common.h>    /* PROTOTYPE_ALLOWED, etc. */
#include <adcp.h>      /* ANCILLARY_1_TYPE, etc. */
#include "tran_bbp.h"  /* BBP_ENSEMBLE_TYPE, etc. */
#include "tran_dcl.h"

/**************************************************************************/
#if PROTOTYPE_ALLOWED
void fill_ancil1(ANCILLARY_1_TYPE *a, BBP_ENSEMBLE_TYPE *ens)
#else
void fill_ancil1(a, ens)
   ANCILLARY_1_TYPE *a;
   BBP_ENSEMBLE_TYPE *ens;
#endif
{
   BBP_LEADER_TYPE *ld;

   ld = &(ens->leader);

   a->tr_temp          = ld->avg_temperature * 0.01;
   /* It is not clear from the documentation whether this test
      is necessary; we could probably find out with a little experimentation.
   */
   if (ens->conf.use_default_sound_speed)
      a->snd_spd_used   = 1536.0;
   else
      a->snd_spd_used   = ens->conf.sound_speed * 0.01;
   a->mn_heading        = ld->avg_heading * 0.01;
   a->pgs_sample        = ld->n_raw_ens * ens->conf.pings_per_ens;
}

/**************************************************************************/
/* I don't see much in ancillary_2 that can be filled from the BBP
   data types.
*/
/**************************************************************************/

#if PROTOTYPE_ALLOWED
void fill_ancil2(ANCILLARY_2_TYPE *a, BBP_ENSEMBLE_TYPE *ens)
#else
void fill_ancil2(a, ens)
   ANCILLARY_2_TYPE *a;
   BBP_ENSEMBLE_TYPE *ens;
#endif
{
   a->mn_pitch =      ens->leader.avg_pitch * 0.01;
   a->mn_roll  =      ens->leader.avg_roll  * 0.01;
   a->last_good_bin = ens->conf.n_bins;
}

/**************************************************************************/

/* Configuration should need to be filled only once per input file,
   so a single function might as well handle all fields, whether there
   is information available or not.
*/
/**************************************************************************/

#if PROTOTYPE_ALLOWED
void fill_config1(CONFIGURATION_1_TYPE *c, BBP_CONFIGURATION_TYPE *bbp_conf)
#else
void fill_config1(c, bbp_conf)
   CONFIGURATION_1_TYPE *c;
   BBP_CONFIGURATION_TYPE *bbp_conf;
#endif
{
   char *fhstr;
   int fhval;

   if (bbp_conf->avg_method == 0)
      c->avg_interval  = (float)(bbp_conf->avg_interval / 100);
   else
      c->avg_interval  = BADFLOAT;

   c->compensation = 1;      /* always bit 0, for heading */
   if (bbp_conf->no_PR_compensation == 0)
      c->compensation |= 6;  /* turn on bits 1 and 2 */
   c->num_bins     = bbp_conf->n_bins;
   c->tr_depth     = bbp_conf->adcp_depth * 0.01;
   c->bin_length   = bbp_conf->bin_length * 0.01;
   c->pls_length   = bbp_conf->xmit_pulse_len * 0.01;

   c->blank_length = bbp_conf->blank * 0.01;

   c->ping_interval= bbp_conf->ping_interval * 0.01;

   /* c->bot_track  is available only if there is an FH command in
      the direct commands list.  For consistency with loadping, we
      set bot_track = 0 if there is no FH command or if it is FH00255,
      else set it to the no. of profiling pings per BT ping,NOTE THAT
      BB has two sets of direct commands  */

   if (bbp_conf->direct_cmd_size == 0 || 
      (fhstr = strstr(bbp_conf->direct_cmd, "FH")) == NULL ||
      (fhval = atoi(fhstr+2)) == 255) 
      if (bbp_conf->direct_cmd2_size == 0 || 
         (fhstr = strstr(bbp_conf->direct_cmd2, "FH")) == NULL ||
         (fhval = atoi(fhstr+2)) == 255) 
             c->bot_track  = 0;
      else
             c->bot_track = fhval;
   else
      c->bot_track = fhval;

   c->pgs_ensemble  = bbp_conf->pings_per_ens;
   c->ens_threshold = BADSHORT; /* (%     ) threshold: %good in ens.   */
   c->ev_threshold  = BADSHORT; /* ( mm/s ) Error velocity threshold   */
   c->hd_offset     = bbp_conf->transducer_misalignment * 0.001;
   c->pit_offset    = BADFLOAT;
   c->rol_offset    = BADFLOAT;
   c->unused1       = BADFLOAT;
   c->unused2       = BADFLOAT;
   c->unused3       = BADFLOAT;
   c->freq_transmit = bbp_conf->frequency * 1000;
   c->top_ref_bin   = BADSHORT;
   c->bot_ref_bin   = BADSHORT;
   c->unused4       = BADFLOAT;
   /* I am not sure about the signs on the following.  Fortunately,
      this field does not get used for anything. */
   c->heading_bias  = (bbp_conf->compass_offset + bbp_conf->magnetic_variation) * 0.001;
}

/**************************************************************************/

/* Our present bt structure is minimal; perhaps some time we should expand it,
   by adding additional fields.  No rush, though.
*/
/**************************************************************************/

#if PROTOTYPE_ALLOWED
void fill_bt(BOTTOM_TRACK_TYPE *bt, BBP_LEADER_TYPE *ld)
#else
void fill_bt(bt, ld)
   BOTTOM_TRACK_TYPE *bt;
   BBP_LEADER_TYPE *ld;
#endif
{
   if (ld->bt_u == BADSHORT)
   {
      bt->u = bt->v = bt->depth = BADFLOAT;
   }
   else
   {
      bt->depth = 0.0025 * ((double)ld->bt_range1 + ld->bt_range2
                           + ld->bt_range3 + ld->bt_range4);
      bt->u = ld->bt_u * 0.001;
      bt->v = ld->bt_v * 0.001;
   }
}

/**************************************************************************/

/* Note: our navigation structure is not well defined; we put in
   it whatever is stored at data averaging time, which may be position
   at the end of the ensemble (with UH user exit programs), or
   averaged over the ensemble (with NAVSOFT).
*/

/**************************************************************************/

#define LLSCALE (1.0 / 3600000)

#if PROTOTYPE_ALLOWED
void fill_nav(NAVIGATION_TYPE *n, BBP_ENSEMBLE_TYPE *ens)
#else
void fill_nav(n, ens)
   NAVIGATION_TYPE *n;
   BBP_ENSEMBLE_TYPE *ens;
#endif
{
   TRANSECT_NAV_TYPE *tn;
   double u, v, rad;

   if (!ens->nav_present)
      n->longitude = n->latitude = n->speed = n->direction = BADFLOAT;
   else
   {
      tn = &(ens->nav);
      if (tn->lat == BADLONG)
      {
         n->latitude  = BADFLOAT;
         n->longitude = BADFLOAT;
      }
      else
      {
         n->latitude  = tn->lat * LLSCALE;
         n->longitude = tn->lon * LLSCALE;
      }
      if (tn->u == BADSHORT)
      {
         n->speed     = BADFLOAT;
         n->direction = BADFLOAT;
      }
      else
      {
         u = tn->u * 0.001;
         v = tn->v * 0.001;
         n->speed = sqrt( u*u + v*v );
         if (fabs(u) < 1e-6)  /* Q&D way to prevent the FP error of u = 0 */
            u = 1e-6;
         rad = atan2(v,u);
         n->direction = 90 - 180 * rad / M_PI;
      }
   }
}
/**************************************************************************/
