/***************************************************************

   SET_TOP.C

   This program knocks out bad top bins of underway profiles
   by setting first_good_bin field of ACCESS_VARIABLES_TYPE
   to the desired bin number.

                     Willa Zhu
                     89-01-13
----------------------------------------------------------------

control file structure:

     dbname:    (e.g. WEP)
     speed_threshold: [ 3 ]  { (m/s) of underway limit }
     ref_bin_range: [reference_bins] [ 5 ] to  [ 20 ]
                             { bin range; first bin is 1 }
     first_good_bin:  [ 3 ]  { first_good_bin number }
     time_ranges:
     (list of YMDHMS time pairs:)
        (yy/mm/dd hh:mm:ss) to (yy/mm/dd hh:mm:ss)
        .
        .
****************************************************************/

#include "geninc.h"
#include "adcp.h"    /* ACCESS_VARIABLES_TYPE */
#include "data_id.h"
#include "vector.h"  /* array_mean() */
#include "ioserv.h"  /* check_error(), get_parameters() */
#include "use_db.h"  /* db*_cnf(), get_time_range(), print_time_range() */

#define  sqr(x)  (x)*(x)
#define  good_float(x)  ( (x) < ADJ_BADFLOAT )

/*
Main routine
*/

#if PROTOTYPE_ALLOWED
void do_it(FILE *fp_cnt)
#else
void do_it(fp_cnt)
FILE *fp_cnt;
#endif
{
   int    IERR, TYPE;
   unsigned int N;
   ACCESS_VARIABLES_TYPE access;
   YMDHMS_TIME_TYPE start, end,            /* for time range */
                    this_time;  /* current profile time */
   float *u, *v, mean_u, mean_v;


   /*---------- end of auto declarations for do_it -----------------*/

/***************************************************************
   static variables needed for initialization of
   the parameter array

*/

static   FILE_NAME_TYPE dbname;
static   int   STEPS = 1;
static   int first_good, bin_range[2];
static   float speed_limit;
static   short underway;
static   PARAMETER_LIST_ENTRY_TYPE parameters[] =
   {
      { " dbname:",          " %79s", dbname,       TYPE_STRING },
      { " speed_threshold:", " %f"  , &speed_limit, TYPE_DOUBLE },
      { " ref_bin_range:",   " %d"  , bin_range,    TYPE_INT    },
      { " to",               " %d"  , bin_range+1,  TYPE_INT    },
      { " first_good_bin:",  " %d"  , &first_good,  TYPE_INT    },
      { " time_ranges:"   ,  NULL   , NULL,         0           },
      { NULL,                NULL,    NULL,         0           }
   };                   /* parameters[] */


/***************************************************************/

   if (get_parameters(fp_cnt, parameters, NULL))  exit(-1);
   print_parameters(stdout, parameters, NULL, "\n");
   check_error( (
      (u = (float *) calloc(bin_range[1], sizeof(FLOAT))) == NULL ||
      (v = (float *) calloc(bin_range[1], sizeof(FLOAT))) == NULL ),
      "insufficient memory for u and v arrays");
   if (dbopen_cnf(1, dbname, READ_WRITE, DIR_ON_DISK)) exit(-1);
/*
---> Start the loop through time ranges listed in the control file.
*/
   while (get_time_range(fp_cnt, &start, &end) == 1)
   {
      if (dbsrch_cnf(TIME_SEARCH, (char *)&start)) goto close_db;
      print_time_range(stdout, &start, &end);
      IERR = 0;
/*
---> Start the loop through profiles within the time range.
*/
      while (!IERR && check_time(&this_time, &start, &end))
      {
         TYPE = U;
         N = bin_range[1];
         DBGET_F(&TYPE, u, &N, &IERR);
         if (DBERROR(&IERR, "DBGET_F u")) goto close_db;
         TYPE = V;
         N = bin_range[1];
         DBGET_F(&TYPE, v, &N, &IERR);
         if (DBERROR(&IERR, "DBGET_F v")) goto close_db;
         mean_u = array_mean((u+bin_range[0]-1), (N-bin_range[0]+1));
         mean_v = array_mean((v+bin_range[0]-1), (N-bin_range[0]+1));
         underway = (sqrt(sqr(mean_u)+sqr(mean_v)) >= speed_limit);
         if (underway)
         {
            N = sizeof(ACCESS_VARIABLES_TYPE);
            if (dbget_cnf(ACCESS_VARIABLES, (char *) &access, &N,
               "access")) goto close_db;
            access.first_good_bin = first_good;
            if (dbput_cnf(ACCESS_VARIABLES, (char *) &access, &N,
               "access")) goto close_db;
         }
         DBMOVE(&STEPS, &IERR);   /* IERR is checked at the start of the loop */
      }  /* end of loop through profiles within a time range */
   }  /* end of loop through time ranges read from control file */

   close_db:
      dbclose_cnf();
      printf("\n SET_TOP completed.\n");
}
