/*  reads a flat ieee file of SSS climatology and creates file
    representing "1 day" of SSS records to be used by MOM4.    */

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <malloc.h>
#include <string.h>

#include <netcdf.h>
#include "Tm.h"

void getM4Grid(), getSss(), writeFile(), intrp2d(), intrpTri(), usage();

int icx, jcx;
float *xc, *yc, *c, *c0;
float xc0, dxc, yc0, dyc;
int igx, jgx, ioff;
float *xg, *yg, *g, *wrk, xgmn, xgmx, ytr = -99.0;
double *xgd, *ygd, *tme;

int dt0 = 0, nm2, jtr = 0;
int year, year0;
YMD *tm;
float hr0 = 0.75, dh = 0.25;

char *source = "Levitus Climatology";
char *tcal = "julian";
char tunits[31];
float mVal = 9999.0;

char inFile[121], outFile[121], gspFile[51];
/* char inFile[51], outFile[51], gspFile[51];    */
char prog[81];

float depth = 0.0, spv = 999.999;

mode_t mode = 0644;

int main(argc,argv)
int argc;
char **argv;
{
  int i, ii, j, n;
  char str[81];

  strcpy(prog,argv[0]);
  strcpy(inFile,"EMPTY");
  strcpy(gspFile,"EMPTY");
  strcpy(outFile,"EMPTY");
  n = 1;
  while (n < argc) {
    if (!strcmp(argv[n],"-f")) {
      n++;
      if (n >= argc || !strncmp(argv[n],"-",1)) {
        printf("Error: for option -f an input file list must be given.\n");
        usage();
        exit(0);
      }
      strcpy(inFile, argv[n]);
    } else if (!strcmp(argv[n],"-g")) {
      n++;
      if (n >= argc || !strncmp(argv[n],"-",1)) {
        printf("Error: for option -g a grid/mask file must be given.\n");
        usage();
        exit(0);
      }
      strcpy(gspFile, argv[n]);
    } else if (!strcmp(argv[n],"-y")) {
      n++;
      if (n >= argc || sscanf(argv[n],"%f",&ytr) != 1) {
        printf("Error: for option -y a latitude must be given.\n");
        usage();
        exit(0);
      }
    } else if (!strcmp(argv[n],"-o")) {
      n++;
      if (n >= argc || !strncmp(argv[n],"-",1)) {
        printf("Error: for option -o an output file must be given.\n");
        usage();
        exit(0);
      }
      strcpy(outFile, argv[n]);
    } else if (!strcmp(argv[n],"-d")) {
      n++;
      if (n >= argc || !strncmp(argv[n],"-",1)) {
        printf("Error: for option -d a date must be given.\n");
        usage();
        exit(0);
      }
      sscanf(argv[n],"%d", &dt0);
    } else if (!strcmp(argv[n],"-h")) {
      usage();
      exit(0);
    } else {
      printf("Error: %s is not an option.\n", argv[n]);
      usage();
      exit(0);
    }
    n++;
  }
  if (!strcmp(inFile,"EMPTY")) {
    printf("Error: An input file must be given.\n");
    usage();
    exit(0);
  }
  if (!strcmp(gspFile,"EMPTY")) {
    printf("Error: An grid/mask file must be given.\n");
    usage();
    exit(0);
  }
  if (!strcmp(outFile,"EMPTY")) {
    printf("Error: An output file must be given.\n");
    usage();
    exit(0);
  }
  if (dt0 == 0) {
    printf("Error: A date must be given.\n");
    usage();
    exit(0);
  }

  nm2 = 7;
  tm = (YMD*)malloc(16*nm2);
  year = dt0 / 10000;
  (tm+1)->year = year;
  (tm+1)->month = (dt0 - year*10000) / 100;
  (tm+1)->day = dt0 % 100;
  year0 = year - 1;
  (tm+1)->year0 = year0;
  (tm+1)->yday = YearDay(*(tm+1));
  (tm+1)->hour = 0;

  tm->yday = (tm+1)->yday - 1;
  tm->year0 = year0;
  tm->hour = 18;
  CalendarDay(tm);

  for (n = 2; n < nm2; n++) {
    (tm+n)->hour = (tm+n-1)->hour + 6;
    if ((tm+n)->hour > 18) {
      (tm+n)->hour = 0;
      (tm+n)->yday = (tm+n-1)->yday + 1;
    } else {
      (tm+n)->yday = (tm+n-1)->yday;
    }
    (tm+n)->year0 = year0;
    CalendarDay(tm+n);
  }

  tme = (double*)malloc(8*nm2);

  sprintf(tunits,"days since %4.4d-%2.2d-%2.2d 00:00:00", tm->year, tm->month, tm->day);

  getSss();

  c  = (float*)malloc(4*icx*jcx*nm2);
  for (n = 0; n < nm2; n++) {
    for (i = 0; i < icx*jcx; i++) {
      *(c+i+n*icx*jcx) = *(c0+i);
    }

    *(tme+n) = hr0 + n * dh;
    printf("%4d-%2.2d-%2.2d %2.2d\n", (tm+n)->year,(tm+n)->month,(tm+n)->day,(tm+n)->hour);

  }

  getM4Grid();

  while (*(yg+jtr) < ytr) {
    jtr++;
  }

  xgmn = *xg;
  xgmx = *(xg+igx-1);

  ioff = -1;
  for (i = 1; i < igx; i++) {
    if (*(xg+i-1) < 0.0 && *(xg+i) >= 0.0) {
      ioff = i;
      break;
    }
  }

  wrk = (float*)malloc(4*igx);
  for (i = 0; i < igx; i++) {
    ii = i+ioff < igx ? i+ioff : i+ioff-igx;
    *(wrk+i) = *(xg+ii);
  }
  for (i = 0; i < igx; i++) {
    *(xg+i) = *(wrk+i) >= 0.0 ? *(wrk+i) : *(wrk+i) + 360.0;
  }

  g = (float*)malloc(4*igx*jgx*nm2);

  intrp2d();

  ioff = igx - ioff;
  for (i = 0; i < igx; i++) {
    ii = i+ioff < igx ? i+ioff : i+ioff-igx;
    *(wrk+i) = *(xg+ii);
  }
  for (i = 0; i < igx; i++) {
    *(xg+i) = *(wrk+i);
    if (*(xg+i) > xgmx) *(xg+i) -= 360.0;
  }

  for (n = 0; n < nm2; n++) {
    for (j = 0; j < jgx; j++) {
      for (i = 0; i < igx; i++) {
        ii = i+ioff < igx ? i+ioff : i+ioff-igx;
        *(wrk+i) = *(g+ii+(j+n*jgx)*igx);
      }
      for (i = 0; i < igx; i++) {
        *(g+i+(j+n*jgx)*igx) = *(wrk+i);
      }
    }
  }

  if (jtr) intrpTri(n);

  writeFile();

}

/* ================================================================= */

void getM4Grid()
{
  int i, ii, n, ncid, stat;
  int ndims, xdid, ydid;
  int nvars, xvid, yvid, xdvid, ydvid;
  size_t len;
  char str[41];

  stat = nc_open(gspFile, NC_NOWRITE, &ncid);
  if (stat != NC_NOERR) {
    printf("Cannot open %s\n", gspFile);
    exit(0);
  }

  stat = nc_inq_ndims(ncid, &ndims);
  if (stat != NC_NOERR) {
    printf("Cannot get number of dimensions\n");
    exit(0);
  }

  xdid = -1;
  ydid = -1;
  for (n = 0; n < ndims; n++) {
    stat = nc_inq_dim(ncid, n, str, &len);
    if (stat != NC_NOERR) {
      printf("Cannot get dimensions\n");
      exit(0);
    }
    if (!strncmp(str,"grid_x_T",8)) {
      xdid = n;
      igx = len;
    } else if (!strncmp(str,"grid_y_T",8)) {
      ydid = n;
      jgx = len;
    }
  }
  if (xdid < 0 || ydid < 0) {
    printf("Cannot get dimension ids: x:%d y:%d\n", xdid, ydid);
    exit(0);
  }

  xg = (float*)malloc(4*igx);
  yg = (float*)malloc(4*jgx);
  xgd = (double*)malloc(8*igx*jgx);
  ygd = (double*)malloc(8*igx*jgx);

  stat = nc_inq_nvars(ncid, &nvars);
  if (stat != NC_NOERR) {
    printf("Cannot get number of variables\n");
    exit(0);
  }
  xvid = -1;
  yvid = -1;
  xdvid = -1;
  ydvid = -1;
  for (n = 0; n < nvars; n++) {
    stat = nc_inq_varname(ncid, n, str);
    if (stat != NC_NOERR) {
      printf("Cannot get variables\n");
      exit(0);
    }
    if (!strncmp(str,"grid_x_T",8)) {
      xvid = n;
    } else if (!strncmp(str,"grid_y_T",8)) {
      yvid = n;
    } else if (!strncmp(str,"x_T",3)) {
      xdvid = n;
    } else if (!strncmp(str,"y_T",3)) {
      ydvid = n;
    }
  }
  if (xvid < 0 || yvid < 0) {
    printf("Cannot get variable ids: x:%d y:%d\n", xvid, yvid);
    exit(0);
  }
  if (xdvid < 0 || ydvid < 0) {
    printf("Cannot get variable ids: x:%d y:%d\n", xvid, yvid);
    exit(0);
  }

  stat = nc_get_var_float(ncid, xvid, xg);
  if (stat != NC_NOERR) {
    printf("Cannot get variable %s\n", "grid_x_T");
    exit(0);
  }
  stat = nc_get_var_float(ncid, yvid, yg);
  if (stat != NC_NOERR) {
    printf("Cannot get variable %s\n", "grid_y_T");
    exit(0);
  }
  stat = nc_get_var_double(ncid, xdvid, xgd);
  if (stat != NC_NOERR) {
    printf("Cannot get variable %s\n", "x_T");
    exit(0);
  }
  stat = nc_get_var_double(ncid, ydvid, ygd);
  if (stat != NC_NOERR) {
    printf("Cannot get variable %s\n", "y_T");
    exit(0);
  }

  stat = nc_close(ncid);
  if (stat != NC_NOERR) {
    printf("Error closing %s\n", gspFile);
  }

}

/* ================================================================= */

void getSss()
{
  int i, ii, n, toff, ncid, stat;
  int ndims, xdid, ydid;
  int nvars, xvid, yvid, tvid, svid;
  size_t len, start[4], count[4];
  char str[41];

  stat = nc_open(inFile, NC_NOWRITE, &ncid);
  if (stat != NC_NOERR) {
    printf("Cannot open %s\n", inFile);
    exit(0);
  }

  stat = nc_inq_ndims(ncid, &ndims);
  if (stat != NC_NOERR) {
    printf("Cannot get number of dimensions\n");
    exit(0);
  }

  xdid = -1;
  ydid = -1;
  for (n = 0; n < ndims; n++) {
    stat = nc_inq_dim(ncid, n, str, &len);
    if (stat != NC_NOERR) {
      printf("Cannot get dimensions\n");
      exit(0);
    }
    if (!strncmp(str,"grid_x",8)) {
      xdid = n;
      icx = len;
    } else if (!strncmp(str,"grid_y",8)) {
      ydid = n;
      jcx = len;
    }
  }
  if (xdid < 0 || ydid < 0) {
    printf("Cannot get dimension ids: x:%d y:%d\n", xdid, ydid);
    exit(0);
  }

  xc = (float*)malloc(4*icx);
  yc = (float*)malloc(4*jcx);
  c0 = (float*)malloc(4*icx*jcx);

  stat = nc_inq_nvars(ncid, &nvars);
  if (stat != NC_NOERR) {
    printf("Cannot get number of variables\n");
    exit(0);
  }
  xvid = -1;
  yvid = -1;
  tvid = -1;
  svid = -1;
  for (n = 0; n < nvars; n++) {
    stat = nc_inq_varname(ncid, n, str);
    if (stat != NC_NOERR) {
      printf("Cannot get variables\n");
      exit(0);
    }
    if (!strncmp(str,"grid_x",8)) {
      xvid = n;
    } else if (!strncmp(str,"grid_y",8)) {
      yvid = n;
    } else if (!strncmp(str,"time",4)) {
      tvid = n;
    } else if (!strncmp(str,"salt",4)) {
      svid = n;
    }
  }
  if (xvid < 0 || yvid < 0 || tvid < 0 || svid < 0) {
    printf("Cannot get variable ids: x:%d y:%d t:%d s:%d\n", xvid, yvid, tvid, svid);
    exit(0);
  }
  stat = nc_get_var_float(ncid, xvid, xc);
  if (stat != NC_NOERR) {
    printf("Cannot get variable %s\n", "grid_x");
    exit(0);
  }
  stat = nc_get_var_float(ncid, yvid, yc);
  if (stat != NC_NOERR) {
    printf("Cannot get variable %s\n", "grid_y");
    exit(0);
  }

  *start = 0;
  *(start+1) = 0;
  *(start+2) = 0;
  *count = 1;
  *(count+1) = jcx;
  *(count+2) = icx;
  stat = nc_get_vara_float(ncid, svid, start, count, c0);
  if (stat != NC_NOERR) {
    printf("Cannot get variable %s\n", "salt");
    exit(0);
  }

  stat = nc_close(ncid);
  if (stat != NC_NOERR) {
    printf("Error closing %s\n", inFile);
  }

  xc0 = *xc;
  dxc = *(xc+1) - *xc;
  yc0 = *yc;
  dyc = *(yc+1) - *yc;
}

/* ================================================================= */

void writeFile()
{
  int n, ncid, stat;
  int ndims, dimids[3], xdid, ydid, tdid;
  int xvid, yvid, tvid, fvid;
  size_t len, ndx;
  char str[41];

  stat = nc_create(outFile, NC_NOCLOBBER, &ncid);
  if (stat != NC_NOERR) {
    printf("Cannot create %s\n", outFile);
    exit(0);
  }

/* definitions */

  len = igx;
  stat = nc_def_dim(ncid,"grid_x_T", len, &xdid);
  if (stat != NC_NOERR) {
    printf("Cannot define dimension %s\n", "grid_x_T");
    exit(0);
  }

  len = jgx;
  stat = nc_def_dim(ncid,"grid_y_T", len, &ydid);
  if (stat != NC_NOERR) {
    printf("Cannot define dimension %s\n", "grid_y_T");
    exit(0);
  }

  len = nm2;
  stat = nc_def_dim(ncid,"time", NC_UNLIMITED, &tdid);
  if (stat != NC_NOERR) {
    printf("Cannot define dimension %s\n", "time");
    exit(0);
  }

  ndims = 1;
  stat = nc_def_var(ncid, "grid_x_T", NC_FLOAT, ndims, &xdid, &xvid);
  if (stat != NC_NOERR) {
    printf("Cannot define variable %s\n", "grid_x_T");
    exit(0);
  }

  ndims = 1;
  stat = nc_def_var(ncid, "grid_y_T", NC_FLOAT, ndims, &ydid, &yvid);
  if (stat != NC_NOERR) {
    printf("Cannot define variable %s\n", "grid_y_T");
    exit(0);
  }

  ndims = 1;
  stat = nc_def_var(ncid, "time", NC_DOUBLE, ndims, &tdid, &tvid);
  if (stat != NC_NOERR) {
    printf("Cannot define variable %s\n", "time");
    exit(0);
  }

  ndims = 3;
  *dimids = tdid;
  *(dimids+1) = ydid;
  *(dimids+2) = xdid;
  stat = nc_def_var(ncid, "salt", NC_FLOAT, ndims, dimids, &fvid);
  if (stat != NC_NOERR) {
    printf("Cannot define variable %s\n", "salt");
    exit(0);
  }

/* attributes */

  len = strlen("Nominal Longitude of T-cell center");
  stat = nc_put_att_text(ncid, xvid, "long_name", len, "Nominal Longitude of T-cell center");
  if (stat != NC_NOERR) {
    printf("Cannot put attribute %s in %s\n", "long_name", "grid_x_T");
    exit(0);
  }
  len = strlen("degree_east");
  stat = nc_put_att_text(ncid, xvid, "units", len, "degree_east");
  if (stat != NC_NOERR) {
    printf("Cannot put attribute %s in %s\n", "units", "grid_x_T");
    exit(0);
  }
  len = strlen("X");
  stat = nc_put_att_text(ncid, xvid, "cartesian_axis", len, "X");
  if (stat != NC_NOERR) {
    printf("Cannot put attribute %s in %s\n", "cartesian_axis", "grid_x_T");
    exit(0);
  }

  len = strlen("Nominal Latitude of T-cell center");
  stat = nc_put_att_text(ncid, yvid, "long_name", len, "Nominal Latitude of T-cell center");
  if (stat != NC_NOERR) {
    printf("Cannot put attribute %s in %s\n", "long_name", "grid_y_T");
    exit(0);
  }
  len = strlen("degree_north");
  stat = nc_put_att_text(ncid, yvid, "units", len, "degree_north");
  if (stat != NC_NOERR) {
    printf("Cannot put attribute %s in %s\n", "units", "grid_y_T");
    exit(0);
  }
  len = strlen("Y");
  stat = nc_put_att_text(ncid, yvid, "cartesian_axis", len, "Y");
  if (stat != NC_NOERR) {
    printf("Cannot put attribute %s in %s\n", "cartesian_axis", "grid_y_T");
    exit(0);
  }

  len = strlen("Time");
  stat = nc_put_att_text(ncid, tvid, "long_name", len, "Time");
  if (stat != NC_NOERR) {
    printf("Cannot put attribute %s in %s\n", "long_name", "time");
    exit(0);
  }
  len = strlen(tunits);
  stat = nc_put_att_text(ncid, tvid, "units", len, tunits);
  if (stat != NC_NOERR) {
    printf("Cannot put attribute %s in %s\n", "units", "time");
    exit(0);
  }
  len = strlen("T");
  stat = nc_put_att_text(ncid, tvid, "cartesian_axis", len, "T");
  if (stat != NC_NOERR) {
    printf("Cannot put attribute %s in %s\n", "cartesian_axis", "time");
    exit(0);
  }
/*
  len = strlen("");
  stat = nc_put_att_text(ncid, tvid, "modulo", len, "");
  if (stat != NC_NOERR) {
    printf("Cannot put attribute %s in %s\n", "modulo", "time");
    exit(0);
  }
*/
  len = strlen(tcal);
  stat = nc_put_att_text(ncid, tvid, "calendar", len, tcal);
  if (stat != NC_NOERR) {
    printf("Cannot put attribute %s in %s\n", "calendar", "time");
    exit(0);
  }

  len = strlen("sea surface salinity [psu]");
  stat = nc_put_att_text(ncid, fvid, "long_name", len, "sea surface salinity [psu]");
  if (stat != NC_NOERR) {
    printf("Cannot put attribute %s in %s\n", "long_name", "salt");
    exit(0);
  }
  len = strlen("psu");
  stat = nc_put_att_text(ncid, fvid, "units", len, "psu");
  if (stat != NC_NOERR) {
    printf("Cannot put attribute %s in %s\n", "units", "salt");
    exit(0);
  }
  len = 1;
  stat = nc_put_att_float(ncid, fvid, "missing_value", NC_FLOAT, len, &mVal);
  if (stat != NC_NOERR) {
    printf("Cannot put attribute %s in %s\n", "missing_value", "salt");
    exit(0);
  }
  len = 1;
  stat = nc_put_att_float(ncid, fvid, "FillValue", NC_FLOAT, len, &mVal);
  if (stat != NC_NOERR) {
    printf("Cannot put attribute %s in %s\n", "FillValue", "salt");
    exit(0);
  }

  sprintf(str,"NCEP %s", source);
  len = strlen(str);
  stat = nc_put_att_text(ncid, NC_GLOBAL, "source", len, str);
  if (stat != NC_NOERR) {
    printf("Cannot put attribute %s in GLOBAL\n", "source");
    exit(0);
  }
  sprintf(str,"Created %d", dt0);
  len = strlen(str);
  stat = nc_put_att_text(ncid, NC_GLOBAL, "history", len, str);
  if (stat != NC_NOERR) {
    printf("Cannot put attribute %s in GLOBAL\n", "history");
    exit(0);
  }

/* end definitions */

  stat = nc_enddef(ncid);
  if (stat != NC_NOERR) {
    printf("Cannot end def mode\n");
    exit(0);
  }

/* variables */

  stat = nc_put_var_float(ncid, xvid, xg);
  if (stat != NC_NOERR) {
    printf("Cannot put variable in %s\n", "grid_x_T");
    exit(0);
  }

  stat = nc_put_var_float(ncid, yvid, yg);
  if (stat != NC_NOERR) {
    printf("Cannot put variable in %s\n", "grid_y_T");
    exit(0);
  }

  for (n = 0; n < nm2; n++) {
    ndx = n;
    stat = nc_put_var1_double(ncid, tvid, &ndx, tme+n);
    if (stat != NC_NOERR) {
      printf("Cannot put variable in %s\n", "time");
      exit(0);
    }
  }

  stat = nc_put_var_float(ncid, fvid, g);
  if (stat != NC_NOERR) {
    printf("Cannot put variable in %s\n", "salt");
    exit(0);
  }

  stat = nc_close(ncid);
  if (stat != NC_NOERR) {
    printf("Error closing %s\n", outFile);
  }

}

/* ================================================================= */

void intrp2d()
{
  int i, j, iw, ie, js, jn, n;
  float dxw, dxe, dx, dys, dyn, dy;

  for (j = 0; j < jgx-1; j++) {
    js = 0;
    while (*(yc+js+1) < *(yg+j))
      js++;
    jn = js + 1;
    dyn = *(yc+jn) - *(yg+j);
    dys = *(yg+j) - *(yc+js);
    dy = *(yc+jn) - *(yc+js);

    for (i = 0; i < igx; i++) {
      if (*(xc+icx-1) < *(xg+i)) {
        iw = icx - 1;
        ie = 0;
        dxe = *(xc+ie) + 360.0 - *(xg+i);
        dxw = *(xg+i) - *(xc+iw);
        dx = *(xc+ie) + 360.0 - *(xc+iw);
      } else {
        iw = 0;
        while (*(xc+iw+1) < *(xg+i))
          iw++;
        ie = iw + 1;
        dxe = *(xc+ie) - *(xg+i);
        dxw = *(xg+i) - *(xc+iw);
        dx = *(xc+ie) - *(xc+iw);
      }
      for (n = 0; n < nm2; n++) {
        *(g+i+(j+n*jgx)*igx) = (dyn*(dxe * *(c+iw+(js+n*jcx)*icx) + dxw * *(c+ie+(js+n*jcx)*icx)) +
                                dys*(dxe * *(c+iw+(jn+n*jcx)*icx) + dxw * *(c+ie+(jn+n*jcx)*icx))) /
                                       (dx*dy);
      }
    }
  }
}

/* ================================================================= */

void intrpTri()
{
  int i, j, iw, ie, js, jn, n;
  float dxw, dxe, dx, dys, dyn, dy, xgdn, cplr;

  j = jcx - 1;
  cplr = 0.0;
  for (i = 0; i < icx; i++) {
    cplr += *(c0+i+j*icx);
  }
  cplr /= (float)icx;

  for (j = jtr; j < jgx; j++) {
    for (i = 0; i < igx; i++) {
      if (*(ygd+i+j*igx) < *(yc+jcx-1)) {
        js = (int)((*(ygd+i+j*igx) - yc0)/dyc);
        jn = js + 1;
        dyn = *(yc+jn) - *(ygd+i+j*igx);
        dys = *(ygd+i+j*igx) - *(yc+js);
        dy = *(yc+jn) - *(yc+js);
        xgdn = *(xgd+i+j*igx) > 0.0 ? *(xgd+i+j*igx) : *(xgd+i+j*igx) + 360.0;
        if (xgdn > *xc) {
          iw = (int)((xgdn - xc0)/dxc);
          ie = iw + 1;
          dxe = *(xc+ie) - xgdn;
          dxw = xgdn - *(xc+iw);
          dx = *(xc+ie) - *(xc+iw);
        } else {
          iw = icx - 1;
          ie = 0;
          dxe = *(xc+ie) - xgdn;
          dxw = xgdn + 360.0 - *(xc+iw);
          dx = *(xc+ie) + 360.0 - *(xc+iw);
        }
        for (n = 0; n < nm2; n++) {
          *(g+i+(j+n*jgx)*igx) = (dyn*(dxe * *(c+iw+(js+n*jcx)*icx) + dxw * *(c+ie+(js+n*jcx)*icx)) +
                                  dys*(dxe * *(c+iw+(jn+n*jcx)*icx) + dxw * *(c+ie+(jn+n*jcx)*icx))) /
                                         (dx*dy);
        }
      } else {
        for (n = 0; n < nm2; n++) {
          *(g+i+(j+n*jgx)*igx) = cplr;
        }
      }
    }
  }
}

/* ================================================================= */

void usage()
{
  printf("Usage:\n");
  printf(" %s -f inFile -g gspFile [options]\n", prog);
  printf("   -f inFile   - input file \n");
  printf("   -g gspFile  - MOM4 grid_spec netCDF file\n");
  printf("   -y ytr      - \"start\" latitude for tripolar grid\n");
  printf("   -d date     - date (yyyymmdd)\n");
  printf("   -o outFile  - output file\n");
}