/**---------------------------------------------------------------------------
 ** 
 ** load_sbe.c -- 
 ** 
 ** Author          : Pierre Jaccard
 ** Created On      : 1999/08/04 10:56:07
 ** Last Modified By: Pierre Jaccard
 ** Last Modified On: 1999/08/04 12:20:34
 ** Update Count    : 15
 ** Directory       : /home/pego/pcd1/codas3c/gfi/src/apps/ctd/
 ** Version         : 0.0
 ** Status          : Unknown
 ** ---------------------------------------------------------------------- ** 
 ** DESCRIPTION: 
 ** 
 **    Undocumented.
 ** 
 ** ---------------------------------------------------------------------- ** 
 ** REVISIONS: 
 ** ---------------------------------------------------------------------- ** 
 ** CHANGES: 
 **------------------------------------------------------------------------**/

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

   FILE: LOAD_SBE.C
   USAGE: LOAD_SBE <control file name>

   This program loads CTD data from SBE ASCII files into
   a CODAS database. SBE files are SeaBird CTD data files 
	 processed with the SEASOFT programmes.
	 
   Unlike load_ctd where the header information
   are prepended to the data files, this program reads the 
	 header information from a single header file. Unlike the 
	 load_odf, there is one header file for each data file.

   The <control file> must contain the following information:

      DATABASE NAME - the name to use for the CODAS database to be created
      PRODUCER DEFINITION FILE NAME
      SHIP NAME - maximum of 11 characters or "none" to use default NODC code
			CRUISE - maximum of 11 characters
      START_PRESSURE - smallest possible pressure value (usually 0 or 1)
      MAX_PRESSURE - largest pressure value to store in database
      PRESSURE_INCREMENT - the pressure interval in decibars
      ASCII FILE NAME(S) - the name of the ASCII files containing the CTD data
             .             (this can be either data or header files)
             .
             .

   All the data are loaded into one block file unless the
   OPTIMUM_PROFILES_PER_BLOCK figure has been exceeded, in which case a
   new block file is started.

 2000/12/13 PJ
            Modified to load standard header format generated by the new
            version of scan_sbe. 
 *****************************************************************************/

#define GFI_CTD_HEADER

#include "geninc.h"
#include "ioserv.h"
#include "dbsource.h"
#include "use_db.h"
#include "gfimisc.h"
#include "gfictd.h"

typedef struct
{
  int pressure;
  int temperature;
  int conductivity;
  int oxygen;
  int salinity;
  int sigma_t;
} COLUMN_NUMBER_TYPE;

COLUMN_NUMBER_TYPE columns={ 1, 2, 3, 4, 5, 6 };

#define  NMAX    5000    /* maximum array size -- adjust if needed    */
#define  BMAX    100     /* idem for all BOTTLES data per cast        */
#define  LINE_MAX 200    /* Max line of CTD data                      */

int  MAX_PRESSURE;       /* largest pressure value to use in loading 
                            pressure variable                         */
int  START_PRESSURE;     /* smallest possible pressure value 
                            (usually 0 or 1)                          */
int  PRESSURE_INCREMENT; /* set in control file to pressure interval 
														used                                      */
int  N_DATA;             /* no. of pressure, temp, oxygen, salinity 
														values to be added                        */
int  N_PRESSURE;         /* no. of pressure values to store in 
														database                                  */
SHORT pressure[NMAX];
FLOAT data[NMAX], btl_data[BMAX];
FILE_NAME_TYPE dbname, prdname, ascname, hdrname;
FILE_NAME_TYPE asclist, hdrlist, btllist;
FILE_NAME_TYPE btlname, btl_dbname, btl_prdname;
#include "geninc.h"
#include "data_id.h"
#include "ioserv.h"    /* error_found() */
#include "use_db.h"    /* db*_cnf() */


#if PROTOTYPE_ALLOWED
/*
int get_header(FILE *fpasc, CONFIGURATION_2_TYPE *conf,
   ANCILLARY_1_TYPE *anc, YMDHMS_TIME_TYPE *prftime, DMSH_POSITION_TYPE
   position[], char *profile_comment);
*/
int get_temperature(FILE *fpasc, int *nvalues, 
                    FLOAT temp[], FLOAT *anc_max_pressure);
int get_salinity(FILE *fpasc, int *nvalues, FLOAT sal[]);
int get_oxygen(FILE *fpasc, int *nvalues, FLOAT oxy[]);
int get_sigma_t(FILE *fpasc, int *nvalues, FLOAT sig[]);
int get_conductivity(FILE *fpasc, int *nvalues, FLOAT con[]);
int dbaddf_cnf(int type, FLOAT data[], int n, char *msg);
int get_column(FILE *fp, char *var);
#else
/*
int get_header();
*/
int get_temperature();
int get_salinity();
int get_oxygen();
int get_sigma_t();
int get_conductivity();
int dbaddf_cnf();
int get_column();
#endif

#if PROTOTYPE_ALLOWED
void do_it(FILE *fpcnt)
#else
void do_it(fpcnt)
FILE *fpcnt;
#endif
{
  int                  dbid = 1, memory_mode = 0, ierr, iprf, i, j;
	 int                  btl_dbid = 2, load_btl = 0, btl_iprf, btl_db;
   int                  n, col;
   long                 filepos;
   FILE                 *fpasc, *fphdr, *fpbtl;
	 FILE                 *fpasclst, *fphdrlst, *fpbtllst;
	 FILE_NAME_TYPE       path, tmphdr, tmpname, tmpasc, tmpbtl;
   CONFIGURATION_2_TYPE conf;
   ANCILLARY_1_TYPE     anc;
   BTL_ANCILLARY_1_TYPE btl_anc;
   DMSH_POSITION_TYPE   position[2];
   YMDHMS_TIME_TYPE     prftime;
   char                 profile_comment[40];
	 ULONG                btlpos;

   static PARAMETER_LIST_ENTRY_TYPE ctdcnt[] =
   {
      {" DATABASE_NAME:"     , " %79s", dbname             , TYPE_STRING},
      {" DEFINITION_FILE:"   , " %79s", prdname            , TYPE_STRING},
			/*
      " FORMAT:"            , " %4s" , FORMAT             , TYPE_STRING,
			*/
      {" START_PRESSURE:"    , " %d"  , &START_PRESSURE    , TYPE_INT},
      {" MAX_PRESSURE:"      , " %d"  , &MAX_PRESSURE      , TYPE_INT},
      {" PRESSURE_INCREMENT:", " %d"  , &PRESSURE_INCREMENT, TYPE_INT},
			{" HDR_FILES:"         , " %79s", hdrlist            , TYPE_STRING},
			{" ASC_FILES:"         , " %79s", asclist            , TYPE_STRING},
      {NULL                  , NULL   , NULL               , 0}
   };

	 static OPTION_TYPE btl_db_opts[]=
	 {
		 {"end", 0, NULL, (char *) NULL},
		 {"db_name:"   , TYPE_STRING, op_get_param, (char *) btl_dbname },
		 {"def_file:"  , TYPE_STRING, op_get_param, (char *) btl_prdname},
		 {"btl_files:" , TYPE_STRING, op_get_param, (char *) btllist    },
		 {NULL, 0, NULL, (char *) NULL}
	 };
	
   static OPTION_TYPE cols_opts[]=
     {
		 {"end", 0, NULL, (char *) NULL},
     {"pressure="    , TYPE_INT, op_get_param, (char *) &(columns.pressure) },
     {"temperature=" , TYPE_INT, op_get_param, 
      (char *) &(columns.temperature)                                         },
     {"conductivity=", TYPE_INT, op_get_param, 
      (char *) &(columns.conductivity)                                        },
     {"salinity="    , TYPE_INT, op_get_param, (char *) &(columns.salinity) },
     {"sigma_t="     , TYPE_INT, op_get_param, (char *) &(columns.sigma_t)  },
     {"oxygen="      , TYPE_INT, op_get_param, (char *) &(columns.oxygen)   },
		 {NULL, 0, NULL, (char *) NULL}
	 };
       
	 static OPTION_TYPE ctdopts[]=
	 {
		 {"end"            , 0, NULL               , (char *) NULL},
		 {"OPTIONS:"       , 0, NULL               , (char *) NULL},
     {"columns:"       , 1, execute_sub_options, (char *) cols_opts}, 
		 {"bottles:"       , 1, execute_sub_options, (char *) btl_db_opts},
		 {NULL, 0, NULL, (char *) NULL}
	 };
	 
	 if (get_parameters(fpcnt, ctdcnt, NULL)) return;
   dbname[79] = prdname[79] = '\0';
   print_parameters(stdout, ctdcnt, NULL, "\n");
	 
	 strcpy(btl_prdname, "");
	 strcpy(btl_dbname, "");
	 if (error_found( (execute_options(fpcnt, ctdopts, ECHO) <= 0),
										"\nWhile reading load_sbe options.")){
		 exit(-1);
	 }
	 if(strlen(btl_dbname) && strlen(btl_prdname)){ load_btl = 1; }
	 if(load_btl && !(strlen(btllist))){
		 printf("\nYou must specify the list of bottle files\n\n");
		 exit(-1);
	 }

	 /*
		 --> INITIALIZATION OF STRUCTURES FOR UNUSED FIELDS
		 */
   set_byte((UBYTE *) &conf, (UBYTE) '\0', sizeof(CONFIGURATION_2_TYPE));
   set_byte((UBYTE *) &anc, (UBYTE) '\0', sizeof(ANCILLARY_1_TYPE));

   /*---------------------------------------------------------------
       NOTE:  pressures are initialized by equation rather than
              read from the file because there have been instances
              of missing data toward the surface.
     ---------------------------------------------------------------*/
   N_PRESSURE = (MAX_PRESSURE - START_PRESSURE + PRESSURE_INCREMENT) /
		 PRESSURE_INCREMENT;
   if (error_found( (N_PRESSURE > NMAX), "array limit exceeded\n\n")) return;
   for (i = 0; i < N_PRESSURE; i++)
		 pressure[i] = (SHORT) START_PRESSURE + i * PRESSURE_INCREMENT;

	 /*
		 --> CREATE DATABASE
		 */
	 DBCREATE(&dbid, dbname, prdname, &memory_mode, &ierr);
	 if (error_found(ierr, "DBCREATE (ctd_db)")) return;
	 
iprf = 0;
	 btl_iprf = 0;
	 btl_db = 0;
	 fphdrlst = check_fopen(hdrlist, "r");
	 fpasclst = check_fopen(asclist, "r");
	 if(load_btl){
		 fpbtllst = check_fopen(btllist, "r");
	 }
   /*---------------------------------------------------
		 NOTE THAT THERE IS ONE ASCII FILE FOR EACH CAST   
     ---------------------------------------------------*/
   while (getword_nc(fphdrlst, hdrname, sizeof(FILE_NAME_TYPE)) > 0){

		 /* Get corresponding next ascii file */
		 if(error_found( getword_nc(fpasclst, ascname, sizeof(FILE_NAME_TYPE)) 
										 == 0, "\nWhile reading ascii CTD file\n\n")) 
			 goto close;

		 /* Control that it really corresponds to the header file */
		 split_file_path(hdrname, path, tmphdr);
		 split_file_path(ascname, path, tmpasc);
     new_extension(tmpname, tmphdr, ".asc");
     if(strcmp(tmpname, tmpasc)){
       /* 2000/12/13 PJ
        *            Trying also uppercase suffix
        */
       new_extension(tmpname, tmphdr, ".ASC");
       if(strcmp(tmpname, tmpasc)){
         printf(
           "\nERROR: ASC file `%s' does not correspond to HDR file `%s'\n\n",
           tmpasc, tmphdr);
         goto close;
       }
     }

		 /* Initialize the data files: */
		 if ((fphdr = fopen(hdrname, "r")) == NULL){
			 printf("\n ERROR: Cannot open HEADER file %s\n", hdrname);
			 goto close;
		 }
		 printf("     %s\n", hdrname);
		 if ((fpasc = fopen(ascname, "r")) == NULL){
			 printf("\n ERROR: Cannot open ASCII file %s\n\n", ascname);
			 goto close;
		 }
		 printf("     %s\n", ascname);

		 /* Get header information */
		 if (get_gfi_header(fphdr, &conf, &anc, &prftime, position, 
												profile_comment) == 0){

			 /*---------------- CREATE BLOCK ----------------*/
			 if (iprf == 0){
				 
				 /*
					 --> CTD 
					 */ 
				 DBNEWBLK(&ierr);
				 if (error_found(ierr, "DBNEWBLK (ctddb)")) goto close;

				 if (dbadd_cnf(CONFIGURATION_2, (char *) &conf,
											 sizeof(CONFIGURATION_2_TYPE), 
											 "adding configuration (ctddb)")) goto close;

				 if (dbadd_cnf(P, (char *) pressure, 
                       (unsigned int) N_PRESSURE * sizeof(SHORT),
											 "adding pressure (ctddb)")) goto close;
			 }
				 
			 /*------------------ CREATE PROFILE ------------------*/
			 DBNEWPRF(&prftime, &ierr);
			 if (error_found(ierr, "DBNEWPRF (ctddb)")) goto close;

			 /* Load position */
			 if (dbadd_cnf(POSITION, (char *) position, sizeof(position),
										 "adding position")) goto close;

       /*
        * Get column numbers
        */
       col = get_column(fphdr, "pressure");
       if(i < 0) goto close;
       if(i > 0)
         columns.pressure = col;
       col = get_column(fphdr, "temperature");
       if(i < 0) goto close;
       if(i > 0)
         columns.temperature = col;
       col = get_column(fphdr, "salinity");
       if(i < 0) goto close;
       if(i > 0)
         columns.salinity = col;
       col = get_column(fphdr, "oxygen");
       if(i < 0) goto close;
       if(i > 0)
         columns.oxygen = col;
       col = get_column(fphdr, "conductivity");
       if(i < 0) goto close;
       if(i > 0)
         columns.conductivity = col;
       col = get_column(fphdr, "sigma-theta");
       if(i < 0) goto close;
       if(i > 0)
         columns.sigma_t = col;

			 /*----------------------------------------------------------------
				 NOTE:  The data in the ASCII file are read in a column at a
				        time, rather than a line at a time, to cover the case
                where the number of observations is so large as to
                cause a memory shortage.  Hence, to conserve memory,
                only one data array is used to read all the variables.
				 ----------------------------------------------------------------*/
			 /* Scan current file and add each of the data */
			 filepos = ftell(fpasc);
			 if (get_temperature(fpasc, &n, data, &(anc.max_pressure))) goto close;
			 if (dbaddf_cnf(TEMPERATURE, data, n, "adding temperature")) goto close;
			 if (error_found(fseek(fpasc, filepos, 0L), "seek error")) goto close;
			 if (get_salinity(fpasc, &n, data)) goto close;
			 if (dbaddf_cnf(SALINITY, data, n, "adding salinity")) goto close;
			 if (error_found(fseek(fpasc, filepos, 0L), "seek error")) goto close;
			 if (get_oxygen(fpasc, &n, data)) goto close;
			 if (dbaddf_cnf(OXYGEN, data, n, "adding oxygen")) goto close;
			 if (error_found(fseek(fpasc, filepos, 0L), "seek error")) goto close;
			 if (get_sigma_t(fpasc, &n, data)) goto close;
			 if (dbaddf_cnf(SIGMA_T, data, n, "adding sigma_t")) goto close;
			 if (error_found(fseek(fpasc, filepos, 0L), "seek error")) goto close;
			 if (get_conductivity(fpasc, &n, data)) goto close;
			 if (dbaddf_cnf(CONDUCTIVITY, data, n, "adding conductivity")) goto close;

			 /* Load ancillary structure */
			 if (dbadd_cnf(ANCILLARY_1, (char *) &anc, sizeof(ANCILLARY_1_TYPE),
										 "adding ancillary")) goto close;

			 /* Close current profile */
			 DBENDPRF(&ierr);
			 if (error_found(ierr, "DBENDPRF")) goto close;

			 /* Update profile number */
			 iprf++;
			 if (iprf == OPTIMUM_PROFILES_PER_BLOCK){
				 DBENDBLK(&ierr);
				 if (error_found(ierr, "DBENDBLK")) goto close;
				 iprf = 0;
			 }
			 fclose(fphdr);
			 fclose(fpasc);
			 /*
				 --> BTL
				 */
			 if(load_btl > 0){
				 
				 /* Get corresponding bottle file */
				 btlpos = (ULONG) ftell(fpbtllst);
				 if(getword_nc(fpbtllst, btlname, sizeof(FILE_NAME_TYPE)) == 0){
					 /* Reached the end of bottle file */
					 load_btl = -1;
					 goto btl_done;
				 }

				 /* Control that it really corresponds to the header file */
				 split_file_path(hdrname, path, tmphdr);
				 split_file_path(btlname, path, tmpbtl);
				 new_extension(tmpname, tmphdr, ".btl");
				 if(strcmp(tmpname, tmpbtl)){
					 /* There is no bottle file for this cast */
					 if(error_found(fseek(fpbtllst, (long) btlpos, SEEK_SET),
													"\nWhile seeking back list of bottle files\n\n"))
						 goto close;
					 goto btl_done;
				 }
				 
				 /* Try to open the bottle file */
				 if((fpbtl = fopen(btlname, "r")) == NULL){
					 printf("\n ERROR: Cannot open BOTTLE file %s\n", btlname);
					 goto close;
				 }
				 printf("BTL: %s\n", btlname);
				 
				 /* Get bottle data */
				 n = get_sbe_bottles(fpbtl, &anc, &btl_anc, data); 
				 if(error_found(n < 0, "\nWhile retrieving bottle data\n"))
					 goto close;
				 if(n == 0)
					 /* No bottles in file */
					 goto btl_done;
				 
				 /* Load the data */
				 
				 /*
					 --> CREATE/SET DATABASE
					 */
				 if(btl_db){
					 DBSET(&btl_dbid, &ierr);
					 if( error_found(ierr, "DBSET (to btldb)") ) goto close;
				 }
				 if(btl_iprf == 0){
					 if(!btl_db){
						 DBCREATE(&btl_dbid, btl_dbname, btl_prdname, &memory_mode, 
											&ierr);
						 if (error_found(ierr, "DBCREATE (btldb)\n\n")) return;
						 btl_db = 1;
					 }
					 DBNEWBLK(&ierr);
					 if (error_found(ierr, "DBNEWBLK (btldb)")) goto close;
					 if (dbadd_cnf(CONFIGURATION_2, (char *) &conf,
												 sizeof(CONFIGURATION_2_TYPE), 
												 "adding configuration (btldb)")) goto close;
				 }
							 
				 /* Initialize new profile */
				 DBNEWPRF(&prftime, &ierr);
				 if (error_found(ierr, "DBNEWPRF (btldb)")) goto close;
				 
				 /* Load position */
				 if (dbadd_cnf(POSITION, (char *) position, sizeof(position),
											 "adding position (btldb)")) goto close;
				 
				 /* Load the data */
				 for(i=0, j=0; j<n; i+=4, j++){
					 btl_data[j] = data[i];
				 }
				 if (dbaddf_cnf(SALINITY, btl_data, n, "adding salinity (btldb)")) 
					 goto close;
				 for(i=1, j=0; j<n; i+=4, j++){
					 btl_data[j] = data[i];
				 }
				 if (dbaddf_cnf(P, btl_data, n, "adding pressure (btldb)")) 
					 goto close;
				 for(i=2, j=0; j<n; i+=4, j++){
					 btl_data[j] = data[i];
				 }
				 if (dbaddf_cnf(TEMPERATURE, btl_data, n, 
												"adding temperature (btldb)")) 
					 goto close;
				 for(i=3, j=0; j<n; i+=4, j++){
					 btl_data[j] = data[i];
				 }
				 if (dbaddf_cnf(CONDUCTIVITY, btl_data, n, 
												"adding conductivity (btldb)")) 
					 goto close;
				 
				 /* Load ancillary structure */
				 if (dbadd_cnf(ANCILLARY_1, (char *) &anc, 
											 sizeof(BTL_ANCILLARY_1_TYPE),
											 "adding BOTTLE ancillary")) goto close;
				 
				 /* Close current profile */
				 DBENDPRF(&ierr);
				 if (error_found(ierr, "DBENDPRF (btldb)")) goto close;
				 
				 /* Update profile number */
				 btl_iprf++;
				 if (btl_iprf == OPTIMUM_PROFILES_PER_BLOCK){
					 DBENDBLK(&ierr);
					 if (error_found(ierr, "DBENDBLK (btldb)")) goto close;
					 btl_iprf = 0;
				 }
				 fclose(fpbtl);
						 
				 /* Set the database to CTD */
				 DBSET(&dbid, &ierr);
				 if( error_found(ierr, "DBSET (to ctddb)")) goto close;
				
			 btl_done:
				 printf("%s", "");

			 }
			 
			 /* Message */
			 printf("      ...Profile %3d => ", iprf);
			 print_ymdhms_time(stdout, &prftime);
			 printf("\n");
		 } 
		 else{
			 printf("\n ERROR: Scanning header information\n\n");
			 goto close;
		 }

	 } /* end while not end-of-control-file loop */
		 
close:
	 
	 printf("\n\n");
	 DBENDBLK(&ierr);
   error_found(ierr, "DBENDBLK (ctddb)");
   dbclose_cnf();
	 if(btl_db){
		 DBSET(&btl_dbid, &ierr);
		 if( error_found(ierr, "DBSET (to btldb)") ) goto close;
		 DBENDBLK(&ierr);
		 error_found(ierr, "DBENDBLK (btldb)");
		 dbclose_cnf();
	 }

	 return;
}


/* ------------------------------------------------------------------ */

int get_column(FILE *fp, char *var)
{

  char *c, str[LINE_MAX], line[LINE_MAX];
  int col;

  c = (char *) NULL;
  line[0] = '\0';

  fseek(fp, 0, SEEK_SET);
  while( (strstr(line, var) == NULL) 
         || ((c = strstr(line, "# name")) == NULL) ){
    if(fgets(line, LINE_MAX, fp) == NULL)
      return(0);
  }
  
  c += strlen("# name");
  if(sscanf(c, "%d", &col) != 1){
    sprintf(str, "reading column number for variable %s", var);
    error_found(1, str);
    return(-1);
  }

  col++ ;
  
  return(col);
}
    
int make_format(int col_1, int col_2, char *fmt)
{

  int i, i0, i1;
  
  if((col_1 == 0) || (col_2 == 0))
    return(1);

  /*
   * Order column numbers
   */
  i0 = (col_1 > col_2) ? col_2 : col_1;
  i1 = (col_1 < col_2) ? col_2 : col_1;
  
  /*
   * Build format string
   */
  fmt[0] = '\0';
  for(i=1; i<i0; i++)
    strcat(fmt, "%*f ");
  strcat(fmt, "%f ");
  for(i=(i0+1); i<i1; i++)
    strcat(fmt, "%*f ");
  strcat(fmt, "%f");
  
  return(0);
}

#if PROTOTYPE_ALLOWED
int get_temperature(FILE *fpasc, int *nvalues, 
                    FLOAT temp[], FLOAT *anc_max_pressure)
#else
int get_temperature(fpasc, nvalues, temp, anc_max_pressure)
FILE *fpasc;
int *nvalues;
FLOAT temp[], *anc_max_pressure;
#endif
{
   int i, j = -1;
   FLOAT t, p = 0.0;
   char line[LINE_MAX];
   char fmt[LINE_MAX];
   
   /*
    * Get the column numbers
    */

   /*----------------------------------------------------------
       INITIALIZE ARRAY TO BADFLOAT IN CASE OF MISSING DATA,
       PARTICULARLY FOR INITIAL PRESSURE INTERVALS
     ----------------------------------------------------------*/
   for (i = 0; i < N_PRESSURE; i++) temp[i] = BADFLOAT;
   *anc_max_pressure = BADFLOAT;
   if(make_format(columns.pressure, columns.temperature, fmt)){
     printf("\nWARNING: all temperatures to BAD\n");
     *nvalues = N_PRESSURE;
     return(0);
   }

	 /* Skipp column titles */
	 if( fgets(line, LINE_MAX, fpasc) == NULL)
		 return(1);

	 /*-----------------------------------------------
		 SCAN AVAILABLE PROFILE DATA FROM ASCII FILE
		 -----------------------------------------------*/
   *nvalues = 0;
	 while (fgets(line, LINE_MAX, fpasc) != NULL){
     *nvalues += 1;
		 if (sscanf(line, fmt, &p, &t) < 2){
			 printf("\n ERROR: Scanning temperature for record %d", *nvalues);
			 return(1);
		 }
		 if (p <= (FLOAT) MAX_PRESSURE){ /* store only up to MAX_PRESSURE */
			 /* I don't know anything about BAD data coding, so I
					do not perform the test for positive temperature */
			 j = ((int) p - START_PRESSURE) / PRESSURE_INCREMENT; 
			 /* may be missing data at initial pressures */
			 temp[j] = t;
		 }
	 }
	 *nvalues = j + 1;
	 *anc_max_pressure = p;  /* from last data line in file */
	 /* Done */
	 return(0);
}

/* ------------------------------------------------------------------ */

#if PROTOTYPE_ALLOWED
int get_oxygen(FILE *fpasc, int *nvalues, FLOAT oxy[])
#else
int get_oxygen(fpasc, nvalues, oxy)
FILE *fpasc;
int *nvalues;
FLOAT oxy[];
#endif
{
   int i, j = -1;
   FLOAT o, p = 0.0;
   char line[LINE_MAX];
   char fmt[LINE_MAX];

   /*----------------------------------------------------------
       INITIALIZE ARRAYS TO BADFLOAT IN CASE OF MISSING DATA,
       PARTICULARLY FOR INITIAL PRESSURE INTERVALS
     ----------------------------------------------------------*/
   for (i = 0; i < N_PRESSURE; i++) oxy[i] = BADFLOAT;
   if(make_format(columns.pressure, columns.oxygen, fmt)){
     printf("\nWARNING: all oxygen to BAD\n");
     *nvalues = N_PRESSURE;
     return(0);
   }
   
	 /* Skipp column titles */
	 if( fgets(line, LINE_MAX, fpasc) == NULL)
		 return(1);


   while (fgets(line, LINE_MAX, fpasc) != NULL){
		 if (sscanf(line, fmt, &p, &o) < 2){
			 printf("\n ERROR: Scanning oxygen for n = %d", *nvalues+1);
			 return(1);
		 }
		 if (p > (FLOAT) MAX_PRESSURE) break;
		 if (o >= 0){
			 j = ((int) p - START_PRESSURE) / PRESSURE_INCREMENT; 
			 /* may be missing data at initial pressures */
			 oxy[j] = o;  /* BADs coded as negative values */
		 }
   }
   *nvalues = j + 1;
   return(0);
}

/* ------------------------------------------------------------------ */

#if PROTOTYPE_ALLOWED
int get_salinity(FILE *fpasc, int *nvalues, FLOAT sal[])
#else
int get_salinity(fpasc, nvalues, sal)
FILE *fpasc;
int *nvalues;
FLOAT sal[];
#endif
{
   int i, j = -1;
   FLOAT s, p = 0.0;
   char line[LINE_MAX];
   char fmt[LINE_MAX];

	 /* Skipp column titles */
	 if( fgets(line, LINE_MAX, fpasc) == NULL)
		 return(1);

   /*----------------------------------------------------------
       INITIALIZE ARRAYS TO BADFLOAT IN CASE OF MISSING DATA,
       PARTICULARLY FOR INITIAL PRESSURE INTERVALS
     ----------------------------------------------------------*/
   for (i = 0; i < N_PRESSURE; i++) sal[i] = BADFLOAT;
   if(make_format(columns.pressure, columns.salinity, fmt)){
     printf("\nWARNING: all salinity to BAD\n");
     *nvalues = N_PRESSURE;
     return(0);
   }

   while (fgets(line, LINE_MAX, fpasc) != NULL){
		 if (sscanf(line, fmt, &p, &s) < 2){
			 printf("\n ERROR: Scanning salinity for n = %d", *nvalues+1);
			 return(1);
		 }
		 if (p > (FLOAT) MAX_PRESSURE) break;
		 if (s >= 0){
			 j = ((int) p - START_PRESSURE) / PRESSURE_INCREMENT; 
			 /* may be missing data at initial pressures */
			 sal[j] = s;  /* BADs coded as negative values */
		 }
   }
   *nvalues = j + 1;
   return(0);
}

/* ------------------------------------------------------------------ */

#if PROTOTYPE_ALLOWED
int get_sigma_t(FILE *fpasc, int *nvalues, FLOAT sig[])
#else
int get_sigma_t(fpasc, nvalues, sig)
FILE *fpasc;
int *nvalues;
FLOAT sig[];
#endif
{
   int i, j = -1;
   FLOAT c, s, p = 0.0;
   char line[LINE_MAX];
   char fmt_sig[LINE_MAX], fmt_c[LINE_MAX];

	 /* Skipp column titles */
	 if( fgets(line, LINE_MAX, fpasc) == NULL)
		 return(1);

   /*----------------------------------------------------------
       INITIALIZE ARRAYS TO BADFLOAT IN CASE OF MISSING DATA,
       PARTICULARLY FOR INITIAL PRESSURE INTERVALS
     ----------------------------------------------------------*/
   for (i = 0; i < N_PRESSURE; i++) sig[i] = BADFLOAT;
   if(make_format(columns.pressure, columns.sigma_t, fmt_sig)
      || make_format(columns.pressure, columns.conductivity, fmt_c)){
     printf("\nWARNING: all sigma_t to BAD\n");
     *nvalues = N_PRESSURE;
     return(0);
   }

   while (fgets(line, LINE_MAX, fpasc) != NULL){
		 /* 1998/11/24 PJ
				           Need to read conductivity for testing good values
									 of sigma_t (see below) */
     
		 if (sscanf(line, fmt_sig, &p, &s) < 2){
			 printf("\n ERROR: Scanning sigma_t for n = %d", *nvalues+1);
			 return(1);
		 }
		 if (sscanf(line, fmt_c, &p, &c) < 2){
			 printf("\n ERROR: Scanning sigma_t for n = %d", *nvalues+1);
			 return(1);
		 }
		 if (p > (FLOAT) MAX_PRESSURE) break;
		 /* sigma_t can be negative, so I remove the test
				if (s >= 0){
		 
				1998/11/24 PJ
				           Some negative values are not correct. The test is done 
									 using measured conductivity */
		 if(c > 0){
			 j = ((int) p - START_PRESSURE) / PRESSURE_INCREMENT; 
			 /* may be missing data at initial pressures */
			 sig[j] = s;  /* BADs coded as negative values */
		 }
   }
   *nvalues = j + 1;
   
   return(0);
}

/* ------------------------------------------------------------------ */

#if PROTOTYPE_ALLOWED
int get_conductivity(FILE *fpasc, int *nvalues, FLOAT con[])
#else
int get_conductivity(fpasc, nvalues, con)
FILE *fpasc;
int *nvalues;
FLOAT con[];
#endif
{
   int i, j = -1;
   FLOAT c, p = 0.0;
   char line[LINE_MAX];
   char fmt[LINE_MAX];

	 /* Skipp column titles */
	 if( fgets(line, LINE_MAX, fpasc) == NULL)
		 return(1);

   /*----------------------------------------------------------
       INITIALIZE ARRAYS TO BADFLOAT IN CASE OF MISSING DATA,
       PARTICULARLY FOR INITIAL PRESSURE INTERVALS
     ----------------------------------------------------------*/
   for (i = 0; i < N_PRESSURE; i++) con[i] = BADFLOAT;
   if(make_format(columns.pressure, columns.conductivity, fmt)){
     printf("\nWARNING: all conductivities to BAD\n");
     *nvalues = N_PRESSURE;
     return(0);
   }

   while (fgets(line, LINE_MAX, fpasc) != NULL){
		 if (sscanf(line, fmt, &p, &c) < 2){
			 printf("\n ERROR: Scanning conductivity for n = %d", *nvalues+1);
			 return(1);
		 }
		 if (p > (FLOAT) MAX_PRESSURE) break;
		 if (c >= 0){
			 j = ((int) p - START_PRESSURE) / PRESSURE_INCREMENT; 
			 /* may be missing data at initial pressures */
			 con[j] = c;  /* BADs coded as negative values */
		 }
   }
   *nvalues = j + 1;
   return(0);
}




/* ------------------------------------------------------------------ */

#if PROTOTYPE_ALLOWED 
int dbaddf_cnf(int type, FLOAT data[], int n, char *msg)
#else
int dbaddf_cnf(type, data, n, msg)
int type;
FLOAT data[];
int n;
char *msg;
#endif
{
   int ierr;
   unsigned int nbad = 0;
   char badmsg[40];

   DBADD_F(&type, data, (unsigned int *)&n, &nbad, &ierr);
   if (error_found(ierr, msg)) return(ierr);
   strcpy(badmsg, "bad values ");
   strcat(badmsg, msg);
   error_found((int)nbad, badmsg);
   return((int)nbad);
}

