/**---------------------------------------------------------------------------
 ** 
 ** load_.c -- 
 ** 
 ** Author          : Pierre Jaccard
 ** Created On      : 1999/07/31 21:19:09
 ** Last Modified By: Pierre Jaccard
 ** Last Modified On: 1999/09/21 13:52:11
 ** Update Count    : 15
 ** Directory       : /pcdata1/jaccard/codas3c/gfi/src/apps/nbr/
 ** Version         : 0.0
 ** Status          : Unknown
 ** ---------------------------------------------------------------------- ** 
 ** DESCRIPTION: 
 ** 
 **    Undocumented.
 ** 
 ** ---------------------------------------------------------------------- ** 
 ** REVISIONS: 
 ** ---------------------------------------------------------------------- ** 
 ** CHANGES: 
 **------------------------------------------------------------------------**/

/* ##################################################################

	-Introduction:

	Utilities used during loading of averaged NB ADCP aw data. This file should
	be included in the main processing programme.

	##################################################################
*/

#ifndef load__C_code_already_included
#define load__C_code_already_included

#include "load_.h"

/* ##################################################################
	 -Initializations:
	 ################################################################## */

/* ------------------------------------------------------------------
	 --Close Profile:
	 ------------------------------------------------------------------ */

#if PROTOTYPE_ALLOWED
int close_prf()
#else
int close_prf()
#endif
{

	int error;

	if(db->new_profile_is_open){
		DBENDPRF(&error);
		if(DBERROR(&error, "DBENDPRF"))
			return(1);
	}

	return(0);
}

/* ------------------------------------------------------------------
	 --Close Block:
	 ------------------------------------------------------------------ */

#if PROTOTYPE_ALLOWED
int close_blk()
#else
int close_blk()
#endif
{

	int error;

	/* Check if profile is open */
	if(db->new_profile_is_open){
		if(close_prf())
			return(1);
	}
	
	/* Close block */
	if(db->new_block_is_open){
		DBENDBLK(&error);
		if(DBERROR(&error, "DBENDBLK"))
			return(1);
	}

	return(0);

}

/* ------------------------------------------------------------------
	 --Open a new block:
	 ------------------------------------------------------------------ */

#if PROTOTYPE_ALLOWED
int open_blk(LOAD_NBR_TYPE *rec)
#else
int open_blk(rec)
#endif
{

	int error;

	/* check if current block is open */
	if(db->new_block_is_open){
		if(close_blk())
			return(1);
	}
	
	report_msg("\n%%% OPENING NEW BLOCK\n");
	DBNEWBLK(&error);
	if(DBERROR(&error, "DBNEWBLK"))
		return(1);

	return(0);

}

/* ------------------------------------------------------------------
	 --Open a new Profile:
	 ------------------------------------------------------------------ */

#if PROTOTYPE_ALLOWED
int open_prf(LOAD_NBR_TYPE *rec, AVG_NPT_TYPE *npt)
#else
int open_prf(rec, npt)
#endif
{

	YMDHMS_TIME_TYPE time;
	int error;

	/* check if profile is open */
	if(db->new_profile_is_open){
		if(close_prf())
			return(1);
	}
	
	/* Get the profile time */
	yd_to_ymdhmh_time(npt->db.time.yd, year_base, &time); 

	DBNEWPRF(&time, &error);
	if(DBERROR(&error, "DBNEWPRF"))
		return(1);

	return(0);

}

/* ------------------------------------------------------------------
	 --Close Data Base:
	 ------------------------------------------------------------------ */

#if PROTOTYPE_ALLOWED
int close_db()
#else
int close_db()
#endif
{

	int error;

	/* Close current block and profile */
	close_prf();
	close_blk();
	
	/* Close the data base */
	DBCLOSE(&error);
	if(DBERROR(&error, "Closing database"))
		 return(CLOSE_ERROR);
	
	return(0);

}

/* ------------------------------------------------------------------
	 --Structures Initializations:

	 Functions taken from [[loatnbp]] files:

   FILE:  initadcp.c

	 Routines for initializing the fields of the adcp.h structures.
	 Values have been selected for consistency with loadping.

	 #include <common.h>
	 #include <adcp.h>
	 ------------------------------------------------------------------ */

#if PROTOTYPE_ALLOWED
void init_ancillary_1(ANCILLARY_1_TYPE *a)
#else
void init_ancillary_1(a)
   ANCILLARY_1_TYPE *a;
#endif
{
   a->tr_temp = a->snd_spd_used = a->best_snd_spd = a->mn_heading = BADFLOAT;
   a->pgs_sample = a->anc6 = a->anc7 = a->anc8 = a->anc9 = a->anc10 = BADSHORT;
}

#if PROTOTYPE_ALLOWED
void init_ancillary_2(ANCILLARY_2_TYPE *a)
#else
void init_ancillary_2(a)
   ANCILLARY_2_TYPE *a;
#endif
{
   a->watrk_hd_misalign = a->botrk_hd_misalign = 
      a->pit_misalign = a->rol_misalign = 0.0;
   a->watrk_scale_factor = a->botrk_scale_factor = 1.0;
   a->unused1 = 
      a->last_temp = a->last_heading = a->last_pitch = a->last_roll = 
      a->mn_pitch = a->mn_roll = 
      a->std_temp = a->std_heading = a->std_pitch = a->std_roll = BADFLOAT;
   a->ocean_depth = a->max_amp_bin = 
      a->anc21 = a->anc22 = a->anc23 = BADSHORT;
   /* a->last_good_bin must be set to conf.num_bins in fill_ancil2 */
}

#if PROTOTYPE_ALLOWED
void init_access_variables(ACCESS_VARIABLES_TYPE *acc)
#else
void init_access_variables(acc)
   ACCESS_VARIABLES_TYPE *acc;
#endif
{
   acc->first_good_bin = 1;
   acc->U_ship_absolute = acc->V_ship_absolute = BADFLOAT;
   acc->user_flag_1 = acc->user_flag_2 = acc->user_flag_3 = acc->user_flag_4 = BADSHORT;
   /* acc->last_good_bin must be set to conf.num_bins elsewhere, prior to DBADD */
}

/* ------------------------------------------------------------------
	 --Initialize Data Base:
	 ------------------------------------------------------------------ */

#if PROTOTYPE_ALLOWED
int init_db(FILE_NAME_TYPE dbname, FILE_NAME_TYPE prdname) 
#else
int init_db(dbname, prdname)
#endif
{

	FILE_NAME_TYPE dirblk;

	int db_id = 1;
	int mem_mode = 0;
	int error = 0;

	/* Build the directory name */
	strcpy(dirblk, dbname);
	strcat(dirblk, "dir.blk");
	
	/* Open data base */
	if(EXISTS(dirblk))
		report_msg("\n%%% APPENDING TO DATABASE\n");
	else
		report_msg("\n%%% CREATING DATABASE\n");
		
	DBCREATE(&db_id, dbname, prdname, &mem_mode, &error);
	if(DBERROR(&error, "Creating database"))
		return(UNABLE_TO_OPEN);
		
	return(0);
}

/* ##################################################################
	 -Filling Structures:

	 These functions could may be designed to use a list defined in [[load_.h]],
	 since much of the code is repeated.
	 ################################################################## */

#if PROTOTYPE_ALLOWED
int fill_config1(LOAD_NBR_TYPE *rec)
#else
int fill_config1(rec)
#endif
{

	PROCESS_CONTROL_TYPE *cnt;
	NBR_CNV_CONTROL_TYPE *cnv;
	NBR_LEADER_TYPE      *l;
	CONFIGURATION_1_TYPE *c;
	NBR_ENSEMBLE_TYPE    *e;
	NBR_TBP_TYPE         *tbp;

	/* Assign pointers */
	cnt = rec->cnt;
	cnv = rec->cnv;
	l   = &(rec->ens.leader);
	c   = &(rec->db.cnf1);
	e   = &(rec->ens);
	tbp = &(rec->ens.leader.time_between_pings);

	/* Fill structure */
	c->avg_interval = (FLOAT) (cnt->avg_time)/100.0;
	c->compensation = 0x01;
	if(option_bits & BIN_MAPPING_BIT)
		c->compensation |= 0x06;
	c->num_bins      = (SHORT) l->number_of_bins;
	c->tr_depth      = cnt->tr_depth;
	c->bin_length    = (FLOAT) e->bin_length;
	c->pls_length    = (FLOAT) l->xmt_pulse_length;
	c->blank_length  = (FLOAT) l->blank_after_xmt;
	c->ping_interval = (FLOAT) (tbp->minutes * 60.0 + tbp->seconds +
															tbp->hundredths/100.0);
	c->bot_track     = (SHORT) cnt->bt_pings;
	c->pgs_ensemble  = (SHORT) l->pings_per_ensemble;
	c->ens_threshold = BADSHORT; 
	c->ev_threshold  = BADSHORT; 
	c->hd_offset     = cnv->tr_mis->heading;
	c->pit_offset    = cnv->tr_mis->pitch;
	c->rol_offset    = cnv->tr_mis->roll;
	c->unused1       = BADFLOAT;
	c->unused2       = BADFLOAT;
	c->unused3       = BADFLOAT;
	c->freq_transmit = cnt->tr_freq;
	c->top_ref_bin   = BADSHORT;
	c->bot_ref_bin   = BADSHORT;
	c->unused4       = BADFLOAT;
	c->heading_bias  = BADFLOAT;

	return(0);
}

#if PROTOTYPE_ALLOWED
int fill_ancillary_1(LOAD_NBR_TYPE *rec)
#else
int fill_ancillary_1(rec)
#endif
{

	UNISTAT_LIST_TYPE *uni, *s;
	NBR_LEADER_TYPE   *l;
	ANCILLARY_1_TYPE  *a;
	int npings;


	/* Assign pointers */
	a = &(rec->db.anc1);
	l = &(rec->ens.leader);
	s = rec->stat_list;

	/* Initialize structure */
	init_ancillary_1(a);

	/* Get the minimal number of pings */
	uni  = s;
	npings = MAXINT;
	while(uni->name != NULL){
		npings = min_val(uni->stat->n_increments, npings);
		uni++;
	}

	/* Fill the structure */
	uni = (UNISTAT_LIST_TYPE *) get_unistat_element(s, ADCP_TEMP_CODE);
	if(uni && (*(uni->stat->sum) < ADJ_BADFLOAT))
		a->tr_temp = (FLOAT) *(uni->stat->sum);
	else
		a->tr_temp = BADFLOAT;

	a->snd_spd_used = (FLOAT) rec->cnv->sound_speed;

	uni = (UNISTAT_LIST_TYPE *) get_unistat_element(s, HEADING_CODE);
	if(uni && (*(uni->stat->sum) < ADJ_BADFLOAT))
		a->mn_heading = (FLOAT) *(uni->stat->sum);
	else
		a->mn_heading = BADFLOAT;
	
	a->pgs_sample = l->pings_per_ensemble * npings;
	a->anc6 = a->anc7 = a->anc8 = a->anc9 = a->anc10 = BADSHORT;

	return(0);

}

#if PROTOTYPE_ALLOWED
int fill_ancillary_2(LOAD_NBR_TYPE *rec)
#else
int fill_ancillary_2(rec)
#endif
{

	UNISTAT_LIST_TYPE *uni, *s;
	ANCILLARY_2_TYPE *a;

	/* Assign pointers */
	a = &(rec->db.anc2);
	s = rec->stat_list;

	/* Initialize structure */
	init_ancillary_2(a);

	a->last_good_bin = (SHORT) rec->ens.leader.number_of_bins;

	/* Fill structure */
	a->pit_misalign = rec->cnv->tr_mis->pitch;
	a->rol_misalign = rec->cnv->tr_mis->roll;
	
	uni = (UNISTAT_LIST_TYPE *) get_unistat_element(s, PITCH_CODE);
	if(uni && (*(uni->stat->sum) < ADJ_BADFLOAT))
		a->mn_pitch = *(uni->stat->sum);
	else
		a->mn_pitch = BADFLOAT;
	uni = (UNISTAT_LIST_TYPE *) get_unistat_element(s, ROLL_CODE);
	if(uni && (*(uni->stat->sum) < ADJ_BADFLOAT))
		a->mn_roll = *(uni->stat->sum);
	else
		a->mn_roll = BADFLOAT;
	uni = (UNISTAT_LIST_TYPE *) get_unistat_element(s, ADCP_TEMP_CODE);
	if(uni && (*(uni->stat->sumsq) < ADJ_BADFLOAT))
		a->std_temp = *(uni->stat->sumsq);
	else
		a->std_temp = BADFLOAT;
	uni = (UNISTAT_LIST_TYPE *) get_unistat_element(s, HEADING_CODE);
	if(uni && (*(uni->stat->sumsq) < ADJ_BADFLOAT))
		a->std_heading = *(uni->stat->sumsq);
	else
		a->std_heading = BADFLOAT;
	uni = (UNISTAT_LIST_TYPE *) get_unistat_element(s, PITCH_CODE);
	if(uni && (*(uni->stat->sumsq) < ADJ_BADFLOAT))
		a->std_pitch = *(uni->stat->sumsq);
	else
		a->std_pitch = BADFLOAT;
	uni = (UNISTAT_LIST_TYPE *) get_unistat_element(s, ROLL_CODE);
	if(uni && (*(uni->stat->sumsq) < ADJ_BADFLOAT))
		a->std_roll = *(uni->stat->sumsq);
	else
		a->std_roll = BADFLOAT;

	return(0);

}

/* ------------------------------------------------------------------
	 --Fill Bottom Track Structure:

	 WARNING: Bottom track velocities are in cm/s, as the water velocities. But
	          the definition file requires bottom track velocities in m/s. These
						must therefore be rescaled here.
	 ------------------------------------------------------------------ */

#if PROTOTYPE_ALLOWED
int fill_bottom_track(LOAD_NBR_TYPE *rec)
#else
int fill_bottom_track(rec)
#endif
{

	BOTTOM_TRACK_TYPE *bt;
	UNISTAT_LIST_TYPE *uni, *s;
	PROCESS_CONTROL_TYPE *cnt;

	double sum, d;
	int n, i;

	/* Assign pointers */
	bt = &(rec->db.bt);
	s  = rec->stat_list;
	cnt = rec->cnt;

	/* Fill the structure */
	uni = (UNISTAT_LIST_TYPE *) get_unistat_element(s, BT_VELOCITY_CODE);
	if(uni && (*(uni->stat->sum) < ADJ_BADFLOAT)){
		bt->u = *(uni->stat->sum);
	  bt->u *= 0.01;  /* cm/s to m/s */
	}
	else
		bt->u = BADFLOAT;
	if(uni && (*(uni->stat->sum+1) < ADJ_BADFLOAT)){
		bt->v = *(uni->stat->sum+1);
	  bt->v *= 0.01;  /* cm/s to m/s */
	}
	else
		bt->v = BADFLOAT;

	uni = (UNISTAT_LIST_TYPE *) get_unistat_element(s, BT_RANGE_CODE);
	if(uni){
		sum = 0.0;
		n = 0;
		for(i=0; i<4; i++){
			d = *(uni->stat->sum+i);
			if(d < ADJ_BADFLOAT){
				sum += d;
				n++;
			}
		}
		if(n > 0)
			sum /= n;
		else
			sum = BADDOUBLE;
	}
	else
		sum = BADDOUBLE;

	if(sum < ADJ_BADFLOAT)
		bt->depth = cnt->tr_depth + sum;
	else
		bt->depth = BADFLOAT;

	return(0);

}

#if PROTOTYPE_ALLOWED
int fill_db_navigation(LOAD_NBR_TYPE *rec, AVG_NPT_TYPE *npt)
#else
int fill_db_navigation(rec, npt)
#endif
{

	NAVIGATION_TYPE *n;
	double u, v, lat, lon;

	/* Assign pointers */
	n = &(rec->db.nav);

	/* Calculate speed and direction */
	u = rec->out.ship.u;
	v = rec->out.ship.v;
	lat = npt->db.pos.lat;
	lon = npt->db.pos.lon;
	
	/* Fill structure */
	if((u < ADJ_BADFLOAT) && (v < ADJ_BADFLOAT)){
		n->speed = sqrt(u*u + v*v) * 3600.0/1852.0;
		n->direction = to360( 90.0 - (atan2(v,u) * 180.0/M_PI) );
	}
	else{
		n->speed = BADDOUBLE;
		n->direction = BADDOUBLE;
	}
	if(lat < ADJ_BADFLOAT)
		n->latitude = lat;
	else
		n->latitude = BADDOUBLE;
	if(lon < ADJ_BADFLOAT)
		n->longitude = lon;
	else
		n->longitude = BADDOUBLE;
	
	return(0);

}

#if PROTOTYPE_ALLOWED
int fill_access_variables(LOAD_NBR_TYPE *rec)
#else
int (rec)
#endif
{

	ACCESS_VARIABLES_TYPE *a;
	NBR_LEADER_TYPE       *l;

	/* Assign pointers */
	a = &(rec->db.acc);
	l = &(rec->ens.leader);

	/* Initialize structure */
	init_access_variables(a);

	a->last_good_bin = (SHORT) l->number_of_bins;

	return(0);
	
}

/* ##################################################################
	 -Load Data:

	 Loading couldbe done trhough a list initialized in [[load_.h]]. However, I
	 would like to test and be more familiar with the database functions before
	 doing this.
	 ################################################################## */

/* ------------------------------------------------------------------
	 Block Variables:
	 ------------------------------------------------------------------ */
#if PROTOTYPE_ALLOWED
int load_block_variables(LOAD_NBR_TYPE *rec)
#else
int load_block_variables(rec)
#endif
{

	NBR_LEADER_TYPE   *l;
	NBR_ENSEMBLE_TYPE *e;
	DEPTH_RANGE_TYPE  *dr;
	PROCESS_CONTROL_TYPE *cnt;
	
	unsigned int size, nbad;
	int i, error, db_type;
	double offset, length;
	FLOAT data[MAX_BINS];

	/* Assignps -aux  pointers */
	l = &(rec->ens.leader);
	e = &(rec->ens);
	dr= &(rec->db.dr);
	cnt = rec->cnt;

	/* Calculate and load cell depth */
	size = l->number_of_bins;
	length = (double) e->bin_length;
	offset = cnt->tr_depth + (double) l->blank_after_xmt +
		0.5 * (length + (double) l->xmt_pulse_length);
	for(i=0; i<(int)size; i++)
		data[i] = (FLOAT) (offset + i*length);
	db_type = DEPTH;
	DBADD_F(&db_type, data, &size, &nbad, &error);
	if(error)
		return(1);
	/* Update depth range */
	dr->min_depth = (SHORT) data[0];
	dr->max_depth = (SHORT) data[size-1];

	/* BLOCK COMMENTS: NONE */
	
	/* Fill and load configuration 1 structure */
	if( fill_config1(rec) )
		return(1);
	if( dbadd_cnf(CONFIGURATION_1, (char *) &(rec->db.cnf1), 
								sizeof(CONFIGURATION_1_TYPE), "adding CONFIGURATION_1") )
		return(1);
	
	/* CONFIGURATION_2: NONE */

	return(0);
	
}

/* ------------------------------------------------------------------
	 --Profile Variables:
	 ------------------------------------------------------------------ */

#if PROTOTYPE_ALLOWED
int load_profile_variables(LOAD_NBR_TYPE *rec, AVG_NPT_TYPE *npt)
#else
int load_profile_variables(rec, npt)
#endif
{

	char func[]="load_profile_variables";

	NBR_ENSEMBLE_TYPE *e;
	NBR_LEADER_TYPE   *l;
	UNISTAT_LIST_TYPE *uni, *s;

	int db_type, error;
  unsigned int nbins, nbad;
	unsigned int ncells;
	int i, j;
	double mn, sd;
	FLOAT vec[8][MAX_BINS];

	/* Assign pointers */
	e = &(rec->ens);
	l = &(rec->ens.leader);
	s = rec->stat_list;

	/* Get number of bins */
	nbins = l->number_of_bins;
	ncells = 4*nbins;

	/* Fill Structures */
	fill_access_variables(rec);
	fill_ancillary_1(rec);
	fill_ancillary_2(rec);
	fill_bottom_track(rec);
	if(option_bits & USE_SCAN_NAV_BIT){
		fill_db_navigation(rec, npt);
	}
 
	/* Additionnal filling */
	if(rec->db.bt.depth < ADJ_BADFLOAT)
		rec->db.anc2.ocean_depth = (SHORT) rec->db.bt.depth;
	
	/* ---------------------------------
		 AMP_SOUND_SCAT, AMP_STD_DEV
		 --------------------------------- */
	if(e->presence_bits & ECHO_INTENSITY_PRESENT){
		uni = (UNISTAT_LIST_TYPE *) get_unistat_element(s, RAW_MEAN_AMP_CODE);
		if(!uni){
			error_msg(func, "No statistics available for [[RAW_MEAN_AMP]]");
			return(1);
		}
		for(i=0; i<(int)nbins; i++){
			mn = *(uni->stat->sum + i);
			sd = sqrt(*(uni->stat->sumsq + i));
			if(mn < ADJ_BADFLOAT){
				vec[0][i] = (FLOAT) mn;
				vec[1][i] = (FLOAT) sd;
			}
			else{
				vec[0][i] = BADFLOAT;
				vec[1][i] = BADFLOAT;
			}
		}
		db_type = AMP_SOUND_SCAT;
		DBADD_F(&db_type, vec[0], &nbins, &nbad, &error);
		if(DBERROR(&error, "adding [[AMP_SOUND_SCAT]]"))
			return(1);
		db_type = AMP_STD_DEV;
		DBADD_F(&db_type, vec[1], &nbins, &nbad, &error);
		if(DBERROR(&error, "adding [[AMP_STD_DEV]]"))
			return(1);
	}
	/* ---------------------------------
		 U, V, W, ERROR_VEL, U_STD_DEV, V_STD_DEV, W_STD_DEV, EV_STD_DEV
		 --------------------------------- */
	if(e->presence_bits & VELOCITY_PRESENT){
		uni = (UNISTAT_LIST_TYPE *) get_unistat_element(s, VELOCITY_CODE);
		if(!uni){
			error_msg(func, "No statistics available for [[VELOCITY]]");
			return(1);
		}
		for(i=0; i<(int)nbins; i++){
			for(j=0; j<4; j++){
				mn = *(uni->stat->sum + 4*i + j);
				sd = sqrt(*(uni->stat->sumsq + 4*i + j));
				if(mn < ADJ_BADFLOAT){
					vec[j][i]   = (FLOAT) mn * 0.01;
					vec[j+4][i] = (FLOAT) sd * 0.01;
				}
				else{
					vec[j][i]   = BADFLOAT;
					vec[j+4][i] = BADFLOAT;
				}
			}
		}
		db_type = U;
		DBADD_F(&db_type, vec[0], &nbins, &nbad, &error);
		if(DBERROR(&error, "adding [[U]]"))
			return(1);
		db_type = V;		
		DBADD_F(&db_type, vec[1], &nbins, &nbad, &error);
		if(DBERROR(&error, "adding [[V]]"))
			return(1);
		db_type = W;
		DBADD_F(&db_type, vec[2], &nbins, &nbad, &error);
		if(DBERROR(&error, "adding [[W]]"))
			return(1);
		db_type = ERROR_VEL;		
		DBADD_F(&db_type, vec[3], &nbins, &nbad, &error);
		if(DBERROR(&error, "adding [[ERROR_VEL]]"))
			return(1);
		db_type = U_STD_DEV;		
		DBADD_F(&db_type, vec[4], &nbins, &nbad, &error);
		if(DBERROR(&error, "adding [[U_STD_DEV]]"))
			return(1);
		db_type = V_STD_DEV;		
		DBADD_F(&db_type, vec[5], &nbins, &nbad, &error);
		if(DBERROR(&error, "adding [[V_STD_DEV]]"))
			return(1);
		db_type = W_STD_DEV;		
		DBADD_F(&db_type, vec[6], &nbins, &nbad, &error);
		if(DBERROR(&error, "adding [[W_STD_DEV]]"))
			return(1);
		db_type = EV_STD_DEV;		
		DBADD_F(&db_type, vec[7], &nbins, &nbad, &error);
		if(DBERROR(&error, "adding [[EV_STD_DEV]]"))
			return(1);	
	}
	/* ---------------------------------
		 WHEATHER: NONE
		 PROFILE_COMMENTS: NONE
		 --------------------------------- */
	/* ---------------------------------
		 PROFILE_FLAGS
		 --------------------------------- */
	set_byte(rec->db.pf, (UBYTE) '\0', MAX_BINS);
	dbadd_cnf(PROFILE_FLAGS, (char *) rec->db.pf, nbins*sizeof(UBYTE), 
						"adding [[PROFILE_FLAGS]]");
	/* ---------------------------------
		 ANCILLARY_1, ANCILLARY_2, ACCESS_VARIABLES
		 --------------------------------- */
	dbadd_cnf(ANCILLARY_1, (char *) &(rec->db.anc1), sizeof(ANCILLARY_1_TYPE),
						"adding [[ANCILLARY_1]]");
	dbadd_cnf(ANCILLARY_2, (char *) &(rec->db.anc2), sizeof(ANCILLARY_2_TYPE),
						"adding [[ANCILLARY_2]]");
	dbadd_cnf(ACCESS_VARIABLES, (char *) &(rec->db.acc), 
						sizeof(ACCESS_VARIABLES_TYPE), "adding [[ACCESS_VARIABLES]]");
	/* ---------------------------------
		 PERCENT_GOOD

		 98/08/25 PJ
		 The test on buffer presence in raw records has been removed, since a
		 custom PCG can be calculated during averaging
		 --------------------------------- */
	/* if(e->presence_bits & PERCENT_GOOD_PRESENT){ */
	uni = (UNISTAT_LIST_TYPE *) get_unistat_element(s, MEAN_PCG_CODE);
	if(!uni){
		error_msg(func, "No statistics available for [[MEAN_PCG]]");
		return(1);
	}
	for(i=0; i<(int)nbins; i++){
		mn = *(uni->stat->sum + i);
    vec[0][i] = BADFLOAT;
		if(mn < ADJ_BADFLOAT)
			vec[0][i] = (FLOAT) mn;
	}
	db_type = PERCENT_GOOD;		
	DBADD_F(&db_type, vec[0], &nbins, &nbad, &error);
	if(DBERROR(&error, "adding [[PERCENT_GOOD]]"))
		return(1);
	/* } */
	/* ---------------------------------
		 PERCENT_3_BEAM: NONE
		 --------------------------------- */
	/* ---------------------------------
		 SPECTRAL_WIDTH: NONE
		 --------------------------------- */
	if(e->presence_bits & SPECTRAL_WIDTH_PRESENT){
		uni = (UNISTAT_LIST_TYPE *) get_unistat_element(s, RAW_SPEC_WIDTH_CODE);
		if(!uni){
			error_msg(func, "No statistics available for [[RAW_SPEC_WIDTH]]");
			return(1);
		}
		for(i=0; i<(int)ncells; i++){
			mn = *(uni->stat->sum + i);
			if(mn < ADJ_BADFLOAT)
				*((FLOAT *) vec + i) = (FLOAT) mn;
			else
				*((FLOAT *) vec + i) = BADFLOAT;
		}
		db_type = RAW_SPECTRAL_WIDTH;		
		DBADD_F(&db_type, (FLOAT *) vec, &ncells, &nbad, &error);
		if(DBERROR(&error, "adding [[RAW_SPECTRAL_WIDTH]]"))
			return(1);

		/* --- */
		uni = (UNISTAT_LIST_TYPE *) get_unistat_element(s, MEAN_SPEC_WIDTH_CODE);
		if(!uni){
			error_msg(func, "No statistics available for [[MEAN_SPEC_WIDTH]]");
			return(1);
		}
		for(i=0; i<(int)nbins; i++){
			mn = *(uni->stat->sum + i);
			if(mn < ADJ_BADFLOAT)
				vec[0][i] = (FLOAT) mn * 0.01;
			else
				vec[0][i] = BADFLOAT;
		}
		db_type = SPECTRAL_WIDTH;		
		DBADD_F(&db_type, vec[0], &nbins, &nbad, &error);
		if(DBERROR(&error, "adding [[SPECTRAL_WIDTH]]"))
			return(1);
	}
	/* ---------------------------------
		 RAW_DOPPLER   : NONE
		 --------------------------------- */
	/* ---------------------------------
		 RAW_AMP
		 --------------------------------- */
	if(e->presence_bits & ECHO_INTENSITY_PRESENT){
		uni = (UNISTAT_LIST_TYPE *) get_unistat_element(s, RAW_ECHO_CODE);
		if(!uni){
			error_msg(func, "No statistics available for [[RAW_ECHO]]");
			return(1);
		}
		for(i=0; i<(int)ncells; i++){
			mn = *(uni->stat->sum + i);
			if(mn < ADJ_BADFLOAT)
				*((FLOAT *) vec + i) = (FLOAT) mn;
			else
				*((FLOAT *) vec + i) = BADFLOAT;
		}
		db_type = RAW_AMP;		
		DBADD_F(&db_type, (FLOAT *) vec, &ncells, &nbad, &error);
		if(DBERROR(&error, "adding [[RAW_AMP]]"))
			return(1);
	}
	/* ---------------------------------
		 RAW_SPECTRAL_WIDTH: NONE
		 BEAM_STATS        : NONE
		 --------------------------------- */
	/* ---------------------------------
		 NAVIGATION, BOTTOM_TRACK
		 --------------------------------- */
	if(option_bits & USE_SCAN_NAV_BIT){
		fill_db_navigation(rec, npt);
		dbadd_cnf(NAVIGATION, (char *) &(rec->db.nav), sizeof(NAVIGATION_TYPE), 
							"adding [[NAVIGATION]]");
	}
	dbadd_cnf(BOTTOM_TRACK, (char *) &(rec->db.bt), sizeof(BOTTOM_TRACK_TYPE),
						"adding [[BOTTOM_TRACK]]");
	/* ---------------------------------
		 DEPTH RANGE: not listed in producer definition file, but it seams that it
		              must be loaded anyway.
		 --------------------------------- */
	dbadd_cnf(DEPTH_RANGE, (char *) &(rec->db.dr), sizeof(DEPTH_RANGE_TYPE),
						"adding [[DEPTH_RANGE]]");

	return(0);
}

/* ------------------------------------------------------------------
	 --Load Data:
	 
	 This is the main function for loading data. It controls itself if a block
	 or profile should be closed or opened. Howvere the corresponding flags must
	 be set to the adequate value prior to call this function.
	 ------------------------------------------------------------------ */

#if PROTOTYPE_ALLOWED
int load_data(LOAD_NBR_TYPE *rec, AVG_NPT_TYPE *npt)
#else
int load_data(rec, npt)
#endif
{

	char func[]="load_data";

	/* 98/09/23 PJ
		          The number of profiles in a block is limited to 512 (cf
							parameter MAX_PROFILE_DIR_SIZE in file dbinc.h. Hence, even if
							blocks should not be generated manually, new ones will have to
							be created anyway if too many profiles should be loaded. 

							Note that there is also a maximum amount of blocks which is set
							to the same threshold. */
	if(db->block_hdr.dir_nentries >= MAX_PROFILE_DIR_SIZE)
		set_flag(rec->flag_list, LOAD_BLOCK_VAR_FLAG, 0, 1);

	/* Get the flag for loading block variables */
	if( get_flag(rec->flag_list, LOAD_BLOCK_VAR_FLAG, 0)){
		/* Open a new block */
		if(open_blk(rec)){
			error_msg(func, "Opening a new block");
			return(1);
		}

		/* Load block variables */
		if( load_block_variables(rec) ){
			error_msg(func, "Loading [[BLOCK_VAR]]");
			return(1);
		}

		/* Update flags */
		set_flag(rec->flag_list, LOAD_BLOCK_VAR_FLAG, 0, 0);
	}

	/* Get the flag for loading profile variables */
	if( get_flag(rec->flag_list, LOAD_PROF_VAR_FLAG, 0)){
		/* Open a new profile */
		if(open_prf(rec, npt)){
			error_msg(func, "Openning a new profile");
			return(1);
		}

		/* Load profile variables */
		if(load_profile_variables(rec, npt) ){
			error_msg(func, "Loading [[PROFILE_VAR]]");
			return(1);
		}

		/* 98/09/23 PJ
			          Closing the profile directly after having loaded the data will
			          update the number of profile entries in the `db' structure */
		if(close_prf())
			return(1);

		/* Update flags */
		set_flag(rec->flag_list, LOAD_PROF_VAR_FLAG, 0, 0);
	}

	return(0);

}

#endif /* load__C_code_already_included */

