Пример #1
0
int main (int argc, char **argv)
{
	extern char *optarg;
	int	errflg = 0;
	int	c;
	int	help = 0;
	int	flag = 0;

	/* MBIO status variables */
	int	status = MB_SUCCESS;
	int	verbose = 0;
	int	error = MB_ERROR_NO_ERROR;
	char	*message;

	/* MBIO read control parameters */
	int	format;
	int	pings;
	int	lonflip;
	double	bounds[4];
	int	btime_i[7];
	int	etime_i[7];
	double	btime_d;
	double	etime_d;
	double	speedmin;
	double	timegap;
	int	beams_bath;
	int	beams_amp;
	int	pixels_ss;
	void	*mbio_ptr = NULL;

	/* mbrollbias control variables */
	int	iformat;
	int	jformat;
	char	ifile[MB_PATH_MAXLINE];
	char	jfile[MB_PATH_MAXLINE];
	int	xdim, ydim;

	/* mbio read values */
	int	rpings;
	int	kind;
	int	time_i[7];
	double	time_d;
	double	navlon;
	double	navlat;
	double	speed;
	double	heading;
	double	distance;
	double	altitude;
	double	sonardepth;
	char	*beamflag = NULL;
	double	*bath = NULL;
	double	*bathlon = NULL;
	double	*bathlat = NULL;
	double	*amp = NULL;
	double	*ss = NULL;
	double	*sslon = NULL;
	double	*sslat = NULL;
	char	comment[MB_COMMENT_MAXLINE];

	/* grid variables */
	double	deglontokm, deglattokm;
	double	mtodeglon, mtodeglat;
	double	dx, dy;
	int	*icount = NULL;
	int	*jcount = NULL;
	struct bathptr	*idata = NULL;
	struct bathptr	*jdata = NULL;
	struct bath	*zone = NULL;
	int	ndatafile;
	double	iaa, ibb, icc, ihh;
	double	jaa, jbb, jcc, jhh;
	double	hx, hy, dd;
	double	isine, icosine, jsine, jcosine;
	double	roll_bias;

	/* matrix parameters */
	int	nmatrix = 3;
	double	matrix[3][3];
	double	vector[3];
	double	xx[3];

	/* output stream for basic stuff (stdout if verbose <= 1,
		stderr if verbose > 1) */
	FILE	*outfp;

	/* other variables */
	int	i, j, k;
	int	ii, jj, kk;
	int	ib, ix, iy, indx;

	/* get current default values */
	status = mb_defaults(verbose,&format,&pings,&lonflip,bounds,
		btime_i,etime_i,&speedmin,&timegap);

	/* set default input and output */
	strcpy (ifile, "\0");
	strcpy (jfile, "\0");

	/* initialize some values */
	pings = 1;
	iformat = format;
	jformat = format;
	btime_i[0] = 1962;
	btime_i[1] = 2;
	btime_i[2] = 21;
	btime_i[3] = 10;
	btime_i[4] = 30;
	btime_i[5] = 0;
	btime_i[6] = 0;
	etime_i[0] = 2062;
	etime_i[1] = 2;
	etime_i[2] = 21;
	etime_i[3] = 10;
	etime_i[4] = 30;
	etime_i[5] = 0;
	etime_i[6] = 0;
	speedmin = 0.0;
	timegap = 1000000000.0;
	bounds[0] = 0.0;
	bounds[1] = 0.0;
	bounds[2] = 0.0;
	bounds[3] = 0.0;
	xdim = 5;
	ydim = 5;

	/* process argument list */
	while ((c = getopt(argc, argv, "VvHhL:l:R:r:F:f:I:i:J:j:D:d:")) != -1)
	  switch (c)
		{
		case 'H':
		case 'h':
			help++;
			break;
		case 'V':
		case 'v':
			verbose++;
			break;
		case 'L':
		case 'l':
			sscanf (optarg,"%d", &lonflip);
			flag++;
			break;
		case 'R':
		case 'r':
			mb_get_bounds(optarg, bounds);
			flag++;
			break;
		case 'F':
		case 'f':
			sscanf (optarg,"%d/%d", &iformat,&jformat);
			flag++;
			break;
		case 'I':
		case 'i':
			sscanf (optarg,"%s", ifile);
			flag++;
			break;
		case 'J':
		case 'j':
			sscanf (optarg,"%s", jfile);
			flag++;
			break;
		case 'D':
		case 'd':
			sscanf (optarg,"%d/%d", &xdim, &ydim);
			flag++;
			break;
		case '?':
			errflg++;
		}

	/* set output stream */
	if (verbose <= 1)
		outfp = stdout;
	else
		outfp = stderr;

	/* if error flagged then print it and exit */
	if (errflg)
		{
		fprintf(outfp,"usage: %s\n", usage_message);
		fprintf(outfp,"\nProgram <%s> Terminated\n",
			program_name);
		error = MB_ERROR_BAD_USAGE;
		exit(error);
		}

	/* print starting message */
	if (verbose == 1 || help)
		{
		fprintf(outfp,"\nProgram %s\n",program_name);
		fprintf(outfp,"Version %s\n",rcs_id);
		fprintf(outfp,"MB-system Version %s\n",MB_VERSION);
		}

	/* print starting debug statements */
	if (verbose >= 2)
		{
		fprintf(outfp,"\ndbg2  Program <%s>\n",program_name);
		fprintf(outfp,"dbg2  Version %s\n",rcs_id);
		fprintf(outfp,"dbg2  MB-system Version %s\n",MB_VERSION);
		fprintf(outfp,"dbg2  Control Parameters:\n");
		fprintf(outfp,"dbg2       verbose:          %d\n",verbose);
		fprintf(outfp,"dbg2       help:             %d\n",help);
		fprintf(outfp,"dbg2       pings:            %d\n",pings);
		fprintf(outfp,"dbg2       lonflip:          %d\n",lonflip);
		fprintf(outfp,"dbg2       btime_i[0]:       %d\n",btime_i[0]);
		fprintf(outfp,"dbg2       btime_i[1]:       %d\n",btime_i[1]);
		fprintf(outfp,"dbg2       btime_i[2]:       %d\n",btime_i[2]);
		fprintf(outfp,"dbg2       btime_i[3]:       %d\n",btime_i[3]);
		fprintf(outfp,"dbg2       btime_i[4]:       %d\n",btime_i[4]);
		fprintf(outfp,"dbg2       btime_i[5]:       %d\n",btime_i[5]);
		fprintf(outfp,"dbg2       btime_i[6]:       %d\n",btime_i[6]);
		fprintf(outfp,"dbg2       etime_i[0]:       %d\n",etime_i[0]);
		fprintf(outfp,"dbg2       etime_i[1]:       %d\n",etime_i[1]);
		fprintf(outfp,"dbg2       etime_i[2]:       %d\n",etime_i[2]);
		fprintf(outfp,"dbg2       etime_i[3]:       %d\n",etime_i[3]);
		fprintf(outfp,"dbg2       etime_i[4]:       %d\n",etime_i[4]);
		fprintf(outfp,"dbg2       etime_i[5]:       %d\n",etime_i[5]);
		fprintf(outfp,"dbg2       etime_i[6]:       %d\n",etime_i[6]);
		fprintf(outfp,"dbg2       speedmin:         %f\n",speedmin);
		fprintf(outfp,"dbg2       timegap:          %f\n",timegap);
		fprintf(outfp,"dbg2       input file 1:     %s\n",ifile);
		fprintf(outfp,"dbg2       input file 2:     %s\n",jfile);
		fprintf(outfp,"dbg2       file 1 format:    %d\n",iformat);
		fprintf(outfp,"dbg2       file 2 format:    %d\n",jformat);
		fprintf(outfp,"dbg2       grid x dimension: %d\n",xdim);
		fprintf(outfp,"dbg2       grid y dimension: %d\n",ydim);
		fprintf(outfp,"dbg2       grid bounds[0]:   %f\n",bounds[0]);
		fprintf(outfp,"dbg2       grid bounds[1]:   %f\n",bounds[1]);
		fprintf(outfp,"dbg2       grid bounds[2]:   %f\n",bounds[2]);
		fprintf(outfp,"dbg2       grid bounds[3]:   %f\n",bounds[3]);
		}

	/* if help desired then print it and exit */
	if (help)
		{
		fprintf(outfp,"\n%s\n",help_message);
		fprintf(outfp,"\nusage: %s\n", usage_message);
		exit(error);
		}

	/* get format if required */
	if (format == 0)
		mb_get_format(verbose,ifile,NULL,&format,&error);

	/* if bounds not specified then quit */
	if (bounds[0] >= bounds[1] || bounds[2] >= bounds[3]
		|| bounds[2] <= -90.0 || bounds[3] >= 90.0)
		{
		fprintf(outfp,"\nGrid bounds not properly specified:\n\t%f %f %f %f\n",bounds[0],bounds[1],bounds[2],bounds[3]);
		fprintf(outfp,"\nProgram <%s> Terminated\n",
			program_name);
		error = MB_ERROR_BAD_PARAMETER;
		exit(error);
		}

	/* calculate grid properties and other values */
	mb_coor_scale(verbose,0.5*(bounds[2]+bounds[3]),&mtodeglon,&mtodeglat);
	deglontokm = 0.001/mtodeglon;
	deglattokm = 0.001/mtodeglat;
	dx = (bounds[1] - bounds[0])/(xdim);
	dy = (bounds[3] - bounds[2])/(ydim);

	/* output info */
	if (verbose >= 0)
		{
		fprintf(outfp,"\nMBROLLBIAS Parameters:\n");
		fprintf(outfp,"Input file 1:     %s\n",ifile);
		fprintf(outfp,"Input file 2:     %s\n",jfile);
		fprintf(outfp,"Region grid bounds:\n");
		fprintf(outfp,"  Longitude: %9.4f %9.4f\n",bounds[0],bounds[1]);
		fprintf(outfp,"  Latitude:  %9.4f %9.4f\n",bounds[2],bounds[3]);
		fprintf(outfp,"Region grid dimensions: %d %d\n",xdim,ydim);
		fprintf(outfp,"Longitude interval: %f degrees or %f km\n",
			dx,dx*deglontokm);
		fprintf(outfp,"Latitude interval:  %f degrees or %f km\n",
			dy,dy*deglattokm);
		fprintf(outfp,"Longitude flipping:   %d\n",lonflip);
		fprintf(outfp,"\n");
		}

	/* allocate memory for counting arrays */
	status = mb_mallocd(verbose,__FILE__,__LINE__,xdim*ydim*sizeof(int),(void **)&icount,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,xdim*ydim*sizeof(int),(void **)&jcount,&error);

	/* if error initializing memory then quit */
	if (error != MB_ERROR_NO_ERROR)
		{
		mb_error(verbose,error,&message);
		fprintf(outfp,"\nMBIO Error allocating data arrays:\n%s\n",
			message);
		fprintf(outfp,"\nProgram <%s> Terminated\n",
			program_name);
		exit(error);
		}

	/* initialize arrays */
	for (i=0;i<xdim*ydim;i++)
		{
		icount[i] = 0;
		jcount[i] = 0;
		}

	/* count data in first swath file */

	/* initialize the first swath file */
	ndatafile = 0;
	if ((status = mb_read_init(
		verbose,ifile,iformat,pings,lonflip,bounds,
		btime_i,etime_i,speedmin,timegap,
		&mbio_ptr,&btime_d,&etime_d,
		&beams_bath,&beams_amp,&pixels_ss,&error)) != MB_SUCCESS)
		{
		mb_error(verbose,error,&message);
		fprintf(outfp,"\nMBIO Error returned from function <mb_read_init>:\n%s\n",message);
		fprintf(outfp,"\nMultibeam File <%s> not initialized for reading\n",ifile);
		fprintf(outfp,"\nProgram <%s> Terminated\n",
			program_name);
		exit(error);
		}

	/* allocate memory for reading data arrays */
	status = mb_mallocd(verbose,__FILE__,__LINE__,beams_bath*sizeof(char),(void **)&beamflag,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,beams_bath*sizeof(double),(void **)&bath,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,beams_bath*sizeof(double),(void **)&bathlon,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,beams_bath*sizeof(double),(void **)&bathlat,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,beams_amp*sizeof(double),(void **)&amp,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,pixels_ss*sizeof(double),(void **)&ss,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,pixels_ss*sizeof(double),(void **)&sslon,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,pixels_ss*sizeof(double),(void **)&sslat,&error);

	/* if error initializing memory then quit */
	if (error != MB_ERROR_NO_ERROR)
		{
		mb_error(verbose,error,&message);
		fprintf(outfp,"\nMBIO Error allocating data arrays:\n%s\n",
			message);
		fprintf(outfp,"\nProgram <%s> Terminated\n",
			program_name);
		exit(error);
		}

	/* loop over reading */
	while (error <= MB_ERROR_NO_ERROR)
		{
		status = mb_read(verbose,mbio_ptr,&kind,
			&rpings,time_i,&time_d,
			&navlon,&navlat,
			&speed,&heading,
			&distance,&altitude,&sonardepth,
			&beams_bath,&beams_amp,&pixels_ss,
			beamflag,bath,amp,bathlon,bathlat,
			ss,sslon,sslat,
			comment,&error);

		/* time gaps are not a problem here */
		if (error == MB_ERROR_TIME_GAP)
			{
			error = MB_ERROR_NO_ERROR;
			status = MB_SUCCESS;
			}

		/* print debug statements */
		if (verbose >= 2)
			{
			fprintf(stderr,"\ndbg2  Ping read in program <%s>\n",program_name);
			fprintf(stderr,"dbg2       kind:           %d\n",kind);
			fprintf(stderr,"dbg2       beams_bath:     %d\n",beams_bath);
			fprintf(stderr,"dbg2       beams_amp:      %d\n",beams_amp);
			fprintf(stderr,"dbg2       pixels_ss:      %d\n",pixels_ss);
			fprintf(stderr,"dbg2       error:          %d\n",error);
			fprintf(stderr,"dbg2       status:         %d\n",status);
			}

		if (error == MB_ERROR_NO_ERROR)
			{
			for (ib=0;ib<beams_bath;ib++)
				if (mb_beam_ok(beamflag[ib]))
				{
				ix = (bathlon[ib] - bounds[0])/dx;
				iy = (bathlat[ib] - bounds[2])/dy;
				if (ix >= 0 && ix < xdim
					&& iy >= 0 && iy < ydim)
					{
					indx = ix + iy*xdim;
					icount[indx]++;
					ndatafile++;
					}
				}
			}
		}
	status = mb_close(verbose,&mbio_ptr,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&beamflag,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&bath,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&bathlon,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&bathlat,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&amp,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&ss,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&sslon,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&sslat,&error);
	status = MB_SUCCESS;
	error = MB_ERROR_NO_ERROR;
	if (verbose >= 2)
		fprintf(outfp,"\n");
	fprintf(outfp,"%d depth points counted in %s\n",
			ndatafile,ifile);

	/* count data in second swath file */

	/* initialize the second swath file */
	ndatafile = 0;
	if ((status = mb_read_init(
		verbose,jfile,jformat,pings,lonflip,bounds,
		btime_i,etime_i,speedmin,timegap,
		&mbio_ptr,&btime_d,&etime_d,
		&beams_bath,&beams_amp,&pixels_ss,&error)) != MB_SUCCESS)
		{
		mb_error(verbose,error,&message);
		fprintf(outfp,"\nMBIO Error returned from function <mb_read_init>:\n%s\n",message);
		fprintf(outfp,"\nMultibeam File <%s> not initialized for reading\n",jfile);
		fprintf(outfp,"\nProgram <%s> Terminated\n",
			program_name);
		exit(error);
		}

	/* allocate memory for reading data arrays */
	status = mb_mallocd(verbose,__FILE__,__LINE__,beams_bath*sizeof(char),(void **)&beamflag,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,beams_bath*sizeof(double),(void **)&bath,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,beams_bath*sizeof(double),(void **)&bathlon,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,beams_bath*sizeof(double),(void **)&bathlat,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,beams_amp*sizeof(double),(void **)&amp,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,pixels_ss*sizeof(double),(void **)&ss,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,pixels_ss*sizeof(double),(void **)&sslon,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,pixels_ss*sizeof(double),(void **)&sslat,&error);

	/* if error initializing memory then quit */
	if (error != MB_ERROR_NO_ERROR)
		{
		mb_error(verbose,error,&message);
		fprintf(outfp,"\nMBIO Error allocating data arrays:\n%s\n",
			message);
		fprintf(outfp,"\nProgram <%s> Terminated\n",
			program_name);
		exit(error);
		}

	/* loop over reading */
	while (error <= MB_ERROR_NO_ERROR)
		{
		status = mb_read(verbose,mbio_ptr,&kind,
			&rpings,time_i,&time_d,
			&navlon,&navlat,
			&speed,&heading,
			&distance,&altitude,&sonardepth,
			&beams_bath,&beams_amp,&pixels_ss,
			beamflag,bath,amp,bathlon,bathlat,
			ss,sslon,sslat,
			comment,&error);

		/* time gaps are not a problem here */
		if (error == MB_ERROR_TIME_GAP)
			{
			error = MB_ERROR_NO_ERROR;
			status = MB_SUCCESS;
			}

		/* print debug statements */
		if (verbose >= 2)
			{
			fprintf(stderr,"\ndbg2  Ping read in program <%s>\n",program_name);
			fprintf(stderr,"dbg2       kind:           %d\n",kind);
			fprintf(stderr,"dbg2       beams_bath:     %d\n",beams_bath);
			fprintf(stderr,"dbg2       beams_amp:      %d\n",beams_amp);
			fprintf(stderr,"dbg2       pixels_ss:      %d\n",pixels_ss);
			fprintf(stderr,"dbg2       error:          %d\n",error);
			fprintf(stderr,"dbg2       status:         %d\n",status);
			}

		if (error == MB_ERROR_NO_ERROR)
			{
			for (ib=0;ib<beams_bath;ib++)
				if (mb_beam_ok(beamflag[ib]))
				{
				ix = (bathlon[ib] - bounds[0])/dx;
				iy = (bathlat[ib] - bounds[2])/dy;
				if (ix >= 0 && ix < xdim
					&& iy >= 0 && iy < ydim)
					{
					indx = ix + iy*xdim;
					jcount[indx]++;
					ndatafile++;
					}
				}
			}
		}
	status = mb_close(verbose,&mbio_ptr,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&beamflag,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&bath,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&bathlon,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&bathlat,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&amp,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&ss,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&sslon,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&sslat,&error);
	status = MB_SUCCESS;
	error = MB_ERROR_NO_ERROR;
	if (verbose >= 2)
		fprintf(outfp,"\n");
	fprintf(outfp,"%d depth points counted in %s\n",
			ndatafile,jfile);

	/* allocate space for data */
	status = mb_mallocd(verbose,__FILE__,__LINE__,xdim*ydim*sizeof(struct bathptr),
			(void **)&idata,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,xdim*ydim*sizeof(struct bathptr),
			(void **)&jdata,&error);
	for (i=0;i<xdim;i++)
		for (j=0;j<ydim;j++)
			{
			k = i*ydim + j;
			idata[k].ptr = NULL;
			jdata[k].ptr = NULL;
			if (icount[k] > 0)
				{
				status = mb_mallocd(verbose,__FILE__,__LINE__,
					icount[k]*sizeof(struct bath),
					(void **)&(idata[k].ptr),&error);
				icount[k] = 0;
				}
			if (jcount[k] > 0)
				{
				status = mb_mallocd(verbose,__FILE__,__LINE__,
					jcount[k]*sizeof(struct bath),
					(void **)&(jdata[k].ptr),&error);
				jcount[k] = 0;
				}
			}

	/* if error initializing memory then quit */
	if (error != MB_ERROR_NO_ERROR)
		{
		mb_error(verbose,error,&message);
		fprintf(outfp,"\nMBIO Error allocating data arrays:\n%s\n",
			message);
		fprintf(outfp,"Try using ping averaging to reduce the number of data.\n");
		fprintf(outfp,"\nProgram <%s> Terminated\n",
			program_name);
		exit(error);
		}

	/* read data in first swath file */

	/* initialize the first swath file */
	ndatafile = 0;
	if ((status = mb_read_init(
		verbose,ifile,iformat,pings,lonflip,bounds,
		btime_i,etime_i,speedmin,timegap,
		&mbio_ptr,&btime_d,&etime_d,
		&beams_bath,&beams_amp,&pixels_ss,&error)) != MB_SUCCESS)
		{
		mb_error(verbose,error,&message);
		fprintf(outfp,"\nMBIO Error returned from function <mb_read_init>:\n%s\n",message);
		fprintf(outfp,"\nMultibeam File <%s> not initialized for reading\n",ifile);
		fprintf(outfp,"\nProgram <%s> Terminated\n",
			program_name);
		exit(error);
		}

	/* allocate memory for reading data arrays */
	status = mb_mallocd(verbose,__FILE__,__LINE__,beams_bath*sizeof(double),(void **)&beamflag,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,beams_bath*sizeof(double),(void **)&bath,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,beams_bath*sizeof(double),(void **)&bathlon,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,beams_bath*sizeof(double),(void **)&bathlat,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,beams_amp*sizeof(double),(void **)&amp,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,pixels_ss*sizeof(double),(void **)&ss,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,pixels_ss*sizeof(double),(void **)&sslon,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,pixels_ss*sizeof(double),(void **)&sslat,&error);

	/* if error initializing memory then quit */
	if (error != MB_ERROR_NO_ERROR)
		{
		mb_error(verbose,error,&message);
		fprintf(outfp,"\nMBIO Error allocating data arrays:\n%s\n",
			message);
		fprintf(outfp,"\nProgram <%s> Terminated\n",
			program_name);
		exit(error);
		}

	/* loop over reading */
	while (error <= MB_ERROR_NO_ERROR)
		{
		status = mb_read(verbose,mbio_ptr,&kind,
			&rpings,time_i,&time_d,
			&navlon,&navlat,
			&speed,&heading,
			&distance,&altitude,&sonardepth,
			&beams_bath,&beams_amp,&pixels_ss,
			beamflag,bath,amp,bathlon,bathlat,
			ss,sslon,sslat,
			comment,&error);

		/* time gaps are not a problem here */
		if (error == MB_ERROR_TIME_GAP)
			{
			error = MB_ERROR_NO_ERROR;
			status = MB_SUCCESS;
			}

		/* print debug statements */
		if (verbose >= 2)
			{
			fprintf(stderr,"\ndbg2  Ping read in program <%s>\n",program_name);
			fprintf(stderr,"dbg2       kind:           %d\n",kind);
			fprintf(stderr,"dbg2       beams_bath:     %d\n",beams_bath);
			fprintf(stderr,"dbg2       beams_amp:      %d\n",beams_amp);
			fprintf(stderr,"dbg2       pixels_ss:      %d\n",pixels_ss);
			fprintf(stderr,"dbg2       error:          %d\n",error);
			fprintf(stderr,"dbg2       status:         %d\n",status);
			}

		if (error == MB_ERROR_NO_ERROR)
			{
			for (ib=0;ib<beams_bath;ib++)
				if (mb_beam_ok(beamflag[ib]))
				{
				ix = (bathlon[ib] - bounds[0])/dx;
				iy = (bathlat[ib] - bounds[2])/dy;
				if (ix >= 0 && ix < xdim
					&& iy >= 0 && iy < ydim)
					{
					indx = ix + iy*xdim;
					zone = idata[indx].ptr;
					zone[icount[indx]].x =
						deglontokm*
						(bathlon[ib] - bounds[0]);
					zone[icount[indx]].y =
						deglattokm*
						(bathlat[ib] - bounds[2]);
					zone[icount[indx]].d = 0.001*bath[ib];
					zone[icount[indx]].h = heading;
					icount[indx]++;
					ndatafile++;
					}
				}
			}
		}
	status = mb_close(verbose,&mbio_ptr,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&beamflag,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&bath,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&bathlon,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&bathlat,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&amp,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&ss,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&sslon,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&sslat,&error);
	status = MB_SUCCESS;
	error = MB_ERROR_NO_ERROR;
	if (verbose >= 2)
		fprintf(outfp,"\n");
	fprintf(outfp,"%d depth points read from %s\n",
			ndatafile,ifile);

	/* read data in second swath file */

	/* initialize the second swath file */
	ndatafile = 0;
	if ((status = mb_read_init(
		verbose,jfile,jformat,pings,lonflip,bounds,
		btime_i,etime_i,speedmin,timegap,
		&mbio_ptr,&btime_d,&etime_d,
		&beams_bath,&beams_amp,&pixels_ss,&error)) != MB_SUCCESS)
		{
		mb_error(verbose,error,&message);
		fprintf(outfp,"\nMBIO Error returned from function <mb_read_init>:\n%s\n",message);
		fprintf(outfp,"\nMultibeam File <%s> not initialized for reading\n",jfile);
		fprintf(outfp,"\nProgram <%s> Terminated\n",
			program_name);
		exit(error);
		}

	/* allocate memory for reading data arrays */
	status = mb_mallocd(verbose,__FILE__,__LINE__,beams_bath*sizeof(char),(void **)&beamflag,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,beams_bath*sizeof(double),(void **)&bath,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,beams_bath*sizeof(double),(void **)&bathlon,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,beams_bath*sizeof(double),(void **)&bathlat,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,beams_amp*sizeof(double),(void **)&amp,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,pixels_ss*sizeof(double),(void **)&ss,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,pixels_ss*sizeof(double),(void **)&sslon,&error);
	status = mb_mallocd(verbose,__FILE__,__LINE__,pixels_ss*sizeof(double),(void **)&sslat,&error);

	/* if error initializing memory then quit */
	if (error != MB_ERROR_NO_ERROR)
		{
		mb_error(verbose,error,&message);
		fprintf(outfp,"\nMBIO Error allocating data arrays:\n%s\n",
			message);
		fprintf(outfp,"\nProgram <%s> Terminated\n",
			program_name);
		exit(error);
		}

	/* loop over reading */
	while (error <= MB_ERROR_NO_ERROR)
		{
		status = mb_read(verbose,mbio_ptr,&kind,
			&rpings,time_i,&time_d,
			&navlon,&navlat,
			&speed,&heading,
			&distance,&altitude,&sonardepth,
			&beams_bath,&beams_amp,&pixels_ss,
			beamflag,bath,amp,bathlon,bathlat,
			ss,sslon,sslat,
			comment,&error);

		/* time gaps are not a problem here */
		if (error == MB_ERROR_TIME_GAP)
			{
			error = MB_ERROR_NO_ERROR;
			status = MB_SUCCESS;
			}

		/* print debug statements */
		if (verbose >= 2)
			{
			fprintf(stderr,"\ndbg2  Ping read in program <%s>\n",program_name);
			fprintf(stderr,"dbg2       kind:           %d\n",kind);
			fprintf(stderr,"dbg2       beams_bath:     %d\n",beams_bath);
			fprintf(stderr,"dbg2       beams_amp:      %d\n",beams_amp);
			fprintf(stderr,"dbg2       pixels_ss:      %d\n",pixels_ss);
			fprintf(stderr,"dbg2       error:          %d\n",error);
			fprintf(stderr,"dbg2       status:         %d\n",status);
			}

		if (error == MB_ERROR_NO_ERROR)
			{
			for (ib=0;ib<beams_bath;ib++)
				if (mb_beam_ok(beamflag[ib]))
				{
				ix = (bathlon[ib] - bounds[0])/dx;
				iy = (bathlat[ib] - bounds[2])/dy;
				if (ix >= 0 && ix < xdim
					&& iy >= 0 && iy < ydim)
					{
					indx = ix + iy*xdim;
					zone = jdata[indx].ptr;
					zone[jcount[indx]].x =
						deglontokm*
						(bathlon[ib] - bounds[0]);
					zone[jcount[indx]].y =
						deglattokm*
						(bathlat[ib] - bounds[2]);
					zone[jcount[indx]].d = 0.001*bath[ib];
					zone[jcount[indx]].h = heading;
					jcount[indx]++;
					ndatafile++;
					}
				}
			}
		}
	status = mb_close(verbose,&mbio_ptr,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&beamflag,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&bath,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&bathlon,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&bathlat,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&amp,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&ss,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&sslon,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&sslat,&error);
	status = MB_SUCCESS;
	error = MB_ERROR_NO_ERROR;
	if (verbose >= 2)
		fprintf(outfp,"\n");
	fprintf(outfp,"%d depth points read from %s\n",
			ndatafile,jfile);

	/* loop over regions */
	for (i=0;i<xdim;i++)
	  for (j=0;j<ydim;j++)
		{
		/* set index */
		indx = i + j*xdim;

		/* print out id info */
		fprintf(outfp,"\nRegion %d (%d %d) bounds:\n",j+i*ydim,i,j);
		fprintf(outfp,"    Longitude: %9.4f %9.4f\n",
			bounds[0]+dx*i,bounds[0]+dx*(i+1));
		fprintf(outfp,"    Latitude:  %9.4f %9.4f\n",
			bounds[2]+dy*j,bounds[2]+dy*(j+1));

		/* get the best fitting planes */
		if (icount[indx] >= MINIMUM_NUMBER_DATA
			&& jcount[indx] >= MINIMUM_NUMBER_DATA)
			{
			/* use data from first data file */
			zone = idata[indx].ptr;

			/* zero the arrays */
			ihh = 0.0;
			hx = 0.0;
			hy = 0.0;
			for (ii=0;ii<nmatrix;ii++)
			  {
			  vector[ii] = 0.0;
			  for (jj=0;jj<nmatrix;jj++)
				matrix[ii][jj] = 0.0;
			  }

			/* construct normal equations */
			for (kk=0;kk<icount[indx];kk++)
			  {
			  ihh += zone[kk].h;
			  hx += sin(DTR * zone[kk].h);
			  hy += cos(DTR * zone[kk].h);
			  xx[0] = 1.0;
			  xx[1] = zone[kk].x;
			  xx[2] = zone[kk].y;
			  for (ii=0;ii<nmatrix;ii++)
			    {
			    vector[ii] += zone[kk].d * xx[ii];
			    for (jj=0;jj<nmatrix;jj++)
				{
				matrix[ii][jj] += xx[ii] * xx[jj];
				}
			    }
			  }

			/* solve the normal equations */
			gauss((double *)matrix,vector,nmatrix,nmatrix,1.0e-08,&error,1);

			/* get the solution */
			iaa = vector[0];
			ibb = vector[1];
			icc = vector[2];
			hx = hx/icount[indx];
			hy = hy/icount[indx];
			dd = sqrt(hx * hx + hy * hy);
			if (dd > 0.0)
				ihh = RTD * atan2((hx/dd), (hy/dd));
			else
				ihh = ihh/icount[indx];
			if (ihh > 360.0)
				ihh = ihh - 360.0;
			else if (ihh < 0.0)
				ihh = ihh + 360.0;

			/* use data from second data file */
			zone = jdata[indx].ptr;

			/* zero the arrays */
			jhh = 0.0;
			hx = 0.0;
			hy = 0.0;
			for (ii=0;ii<nmatrix;ii++)
			  {
			  vector[ii] = 0.0;
			  for (jj=0;jj<nmatrix;jj++)
				matrix[ii][jj] = 0.0;
			  }

			/* construct normal equations */
			for (kk=0;kk<jcount[indx];kk++)
			  {
			  jhh += zone[kk].h;
			  hx += sin(DTR * zone[kk].h);
			  hy += cos(DTR * zone[kk].h);
			  xx[0] = 1.0;
			  xx[1] = zone[kk].x;
			  xx[2] = zone[kk].y;
			  for (ii=0;ii<nmatrix;ii++)
			    {
			    vector[ii] += zone[kk].d * xx[ii];
			    for (jj=0;jj<nmatrix;jj++)
				{
				matrix[ii][jj] += xx[ii] * xx[jj];
				}
			    }
			  }

			/* solve the normal equations */
			gauss((double *)matrix,vector,nmatrix,nmatrix,1.0e-08,&error,1);
			if (error != 0)
				{
				fprintf(outfp,"matrix inversion error: %d\n",error);
				}

			/* get the solution */
			jaa = vector[0];
			jbb = vector[1];
			jcc = vector[2];
			hx = hx/jcount[indx];
			hy = hy/jcount[indx];
			dd = sqrt(hx * hx + hy * hy);
			if (dd > 0.0)
				jhh = RTD * atan2((hx/dd), (hy/dd));
			else
				jhh = jhh/jcount[indx];
			if (jhh > 360.0)
				jhh = jhh - 360.0;
			else if (jhh < 0.0)
				jhh = jhh + 360.0;

			/* report results */
			fprintf(outfp,"First data file:    %s\n",ifile);
			fprintf(outfp,"    Number of data: %d\n",
				icount[indx]);
			fprintf(outfp,"    Mean heading:   %f\n",ihh);
			fprintf(outfp,"    Plane fit:      %f %f %f\n",
				iaa,ibb,icc);
			fprintf(outfp,"Second data file:   %s\n",jfile);
			fprintf(outfp,"    Number of data: %d\n",
				jcount[indx]);
			fprintf(outfp,"    Mean heading:   %f\n",jhh);
			fprintf(outfp,"    Plane fit:      %f %f %f\n",
				jaa,jbb,jcc);

			/* calculate roll bias */
			if (fabs(ihh - jhh) > 90.0)
				{
				isine = sin(DTR*ihh);
				icosine = cos(DTR*ihh);
				jsine = sin(DTR*jhh);
				jcosine = cos(DTR*jhh);
				if (fabs(jcosine-icosine) > 1.0)
					{
					roll_bias = -(ibb - jbb)
						/(jcosine - icosine);
					}
				else
					{
					roll_bias = -(icc - jcc)
						/(isine - jsine);
					}
				fprintf(outfp,"Roll bias:   %f (%f degrees)\n",
					roll_bias,atan(roll_bias)/DTR);
				fprintf(outfp,"Roll bias is positive to starboard, negative to port.\n");
				fprintf(outfp,"A postive roll bias means the vertical reference used by \n    the swath system is biased to starboard, \n    giving rise to shallow bathymetry to port and \n    deep bathymetry to starboard.\n");
				}
			else
				fprintf(outfp,"Track headings too similar to calculate roll bias!\n");
			}
		else
			fprintf(outfp,"Not enough data to proceed!\n");
		}

	/* deallocate space for data */
	for (i=0;i<xdim;i++)
		for (j=0;j<ydim;j++)
			{
			k = i*ydim + j;
			if (icount[k] > 0)
				{
				status = mb_freed(verbose,__FILE__,__LINE__,(void **)&idata[k].ptr,&error);
				}
			if (jcount[k] > 0)
				{
				status = mb_freed(verbose,__FILE__,__LINE__,(void **)&jdata[k].ptr,&error);
				}
			}
	status = mb_freed(verbose,__FILE__,__LINE__,(void **)&idata,&error);
	status = mb_freed(verbose,__FILE__,__LINE__,(void **)&jdata,&error);
	status = mb_freed(verbose,__FILE__,__LINE__,(void **)&icount,&error);
	status = mb_freed(verbose,__FILE__,__LINE__,(void **)&jcount,&error);

	/* check memory */
	if (verbose >= 4)
		status = mb_memory_list(verbose,&error);

	/* print output debug statements */
	if (verbose >= 2)
		{
		fprintf(stderr,"\ndbg2  Program <%s> completed\n",
			program_name);
		fprintf(stderr,"dbg2  Ending status:\n");
		fprintf(stderr,"dbg2       status:  %d\n",status);
		}

	/* end it all */
	exit(error);
}
Пример #2
0
int main (int argc, char **argv)
{
	char program_name[] = "MBHISTOGRAM";
	char help_message[] =  "MBHISTOGRAM reads a swath sonar data file and generates a histogram\n\tof the bathymetry,  amplitude,  or sidescan values. Alternatively, \n\tmbhistogram can output a list of values which break up the\n\tdistribution into equal sized regions.\n\tThe results are dumped to stdout.";
	char usage_message[] = "mbhistogram [-Akind -Byr/mo/da/hr/mn/sc -Dmin/max -Eyr/mo/da/hr/mn/sc -Fformat -G -Ifile -Llonflip -Mnintervals -Nnbins -Ppings -Rw/e/s/n -Sspeed -V -H]";
	extern char *optarg;
	int	errflg = 0;
	int	c;
	int	help = 0;
	int	flag = 0;

	/* MBIO status variables */
	int	status = MB_SUCCESS;
	int	verbose = 0;
	int	error = MB_ERROR_NO_ERROR;
	char	*message;

	/* MBIO read control parameters */
	int	read_datalist = MB_NO;
	char	read_file[MB_PATH_MAXLINE];
	void	*datalist;
	int	look_processed = MB_DATALIST_LOOK_UNSET;
	double	file_weight;
	int	format;
	int	pings;
	int	lonflip;
	double	bounds[4];
	int	btime_i[7];
	int	etime_i[7];
	double	btime_d;
	double	etime_d;
	double	speedmin;
	double	timegap;
	char	file[MB_PATH_MAXLINE];
	int	beams_bath;
	int	beams_amp;
	int	pixels_ss;

	/* MBIO read values */
	void	*mbio_ptr = NULL;
	int	kind;
	int	time_i[7];
	double	time_d;
	double	navlon;
	double	navlat;
	double	speed;
	double	heading;
	double	distance;
	double	altitude;
	double	sonardepth;
	char	*beamflag = NULL;
	double	*bath = NULL;
	double	*bathacrosstrack = NULL;
	double	*bathalongtrack = NULL;
	double	*amp = NULL;
	double	*ss = NULL;
	double	*ssacrosstrack = NULL;
	double	*ssalongtrack = NULL;
	char	comment[MB_COMMENT_MAXLINE];

	/* histogram variables */
	int	mode = MBHISTOGRAM_SS;
	int	gaussian = MB_NO;
	int	nbins = 0;
	int	nintervals = 0;
	double	value_min = 0.0;
	double	value_max = 128.0;
	double	dvalue_bin;
	double	value_bin_min;
	double	value_bin_max;
	double	data_min;
	double	data_max;
	int	data_first = MB_YES;
	double	target_min;
	double	target_max;
	double	*histogram = NULL;
	double	*intervals = NULL;
	double	total;
	double	sum;
	double	p;
	double	target;
	double	dinterval;
	double	bin_fraction;
	int	ibin;

	/* output stream for basic stuff (stdout if verbose <= 1,
		stderr if verbose > 1) */
	FILE	*output;

	int	read_data;
	int	nrec, nvalue;
	int	nrectot = 0;
	int	nvaluetot = 0;
	int	i, j;

	/* get current default values */
	status = mb_defaults(verbose,&format,&pings,&lonflip,bounds,
		btime_i,etime_i,&speedmin,&timegap);

	/* set default input to stdin */
	strcpy (read_file, "stdin");

	/* process argument list */
	while ((c = getopt(argc, argv, "A:a:B:b:D:d:E:e:F:f:GgHhI:i:L:l:M:m:N:n:P:p:R:r:S:s:T:t:Vv")) != -1)
	  switch (c)
		{
		case 'A':
		case 'a':
			sscanf (optarg,"%d", &mode);
			flag++;
			break;
		case 'B':
		case 'b':
			sscanf (optarg,"%d/%d/%d/%d/%d/%d",
				&btime_i[0],&btime_i[1],&btime_i[2],
				&btime_i[3],&btime_i[4],&btime_i[5]);
			btime_i[6] = 0;
			flag++;
			break;
		case 'D':
		case 'd':
			sscanf (optarg,"%lf/%lf", &value_min,&value_max);
			flag++;
			break;
		case 'E':
		case 'e':
			sscanf (optarg,"%d/%d/%d/%d/%d/%d",
				&etime_i[0],&etime_i[1],&etime_i[2],
				&etime_i[3],&etime_i[4],&etime_i[5]);
			etime_i[6] = 0;
			flag++;
			break;
		case 'F':
		case 'f':
			sscanf (optarg,"%d", &format);
			flag++;
			break;
		case 'G':
		case 'g':
			gaussian = MB_YES;
			break;
		case 'H':
		case 'h':
			help++;
			break;
		case 'I':
		case 'i':
			sscanf (optarg,"%s", read_file);
			flag++;
			break;
		case 'L':
		case 'l':
			sscanf (optarg,"%d", &lonflip);
			flag++;
			break;
		case 'M':
		case 'm':
			sscanf (optarg,"%d", &nintervals);
			flag++;
			break;
		case 'N':
		case 'n':
			sscanf (optarg,"%d", &nbins);
			flag++;
			break;
		case 'P':
		case 'p':
			sscanf (optarg,"%d", &pings);
			flag++;
			break;
		case 'R':
		case 'r':
			mb_get_bounds(optarg, bounds);
			flag++;
			break;
		case 'S':
		case 's':
			sscanf (optarg,"%lf", &speedmin);
			flag++;
			break;
		case 'T':
		case 't':
			sscanf (optarg,"%lf", &timegap);
			flag++;
			break;
		case 'V':
		case 'v':
			verbose++;
			break;
		case '?':
			errflg++;
		}

	/* set output stream */
	if (verbose <= 1)
		output = stdout;
	else
		output = stderr;

	/* if error flagged then print it and exit */
	if (errflg)
		{
		fprintf(output,"usage: %s\n", usage_message);
		fprintf(output,"\nProgram <%s> Terminated\n",
			program_name);
		error = MB_ERROR_BAD_USAGE;
		exit(error);
		}

	/* print starting message */
	if (verbose == 1 || help)
		{
		fprintf(output,"\nProgram %s\n",program_name);
		fprintf(output,"Version %s\n",rcs_id);
		fprintf(output,"MB-system Version %s\n",MB_VERSION);
		}

	/* get format if required */
	if (format == 0)
		mb_get_format(verbose,read_file,NULL,&format,&error);

	/* figure out histogram dimensions */
	if (nintervals > 0 && nbins <= 0)
		nbins = 50*nintervals;
	if (nbins <= 0)
		nbins = 16;

	/* print starting debug statements */
	if (verbose >= 2)
		{
		fprintf(output,"\ndbg2  Program <%s>\n",program_name);
		fprintf(output,"dbg2  Version %s\n",rcs_id);
		fprintf(output,"dbg2  MB-system Version %s\n",MB_VERSION);
		fprintf(output,"dbg2  Control Parameters:\n");
		fprintf(output,"dbg2       verbose:    %d\n",verbose);
		fprintf(output,"dbg2       help:       %d\n",help);
		fprintf(output,"dbg2       format:     %d\n",format);
		fprintf(output,"dbg2       pings:      %d\n",pings);
		fprintf(output,"dbg2       lonflip:    %d\n",lonflip);
		fprintf(output,"dbg2       bounds[0]:  %f\n",bounds[0]);
		fprintf(output,"dbg2       bounds[1]:  %f\n",bounds[1]);
		fprintf(output,"dbg2       bounds[2]:  %f\n",bounds[2]);
		fprintf(output,"dbg2       bounds[3]:  %f\n",bounds[3]);
		fprintf(output,"dbg2       btime_i[0]: %d\n",btime_i[0]);
		fprintf(output,"dbg2       btime_i[1]: %d\n",btime_i[1]);
		fprintf(output,"dbg2       btime_i[2]: %d\n",btime_i[2]);
		fprintf(output,"dbg2       btime_i[3]: %d\n",btime_i[3]);
		fprintf(output,"dbg2       btime_i[4]: %d\n",btime_i[4]);
		fprintf(output,"dbg2       btime_i[5]: %d\n",btime_i[5]);
		fprintf(output,"dbg2       btime_i[6]: %d\n",btime_i[6]);
		fprintf(output,"dbg2       etime_i[0]: %d\n",etime_i[0]);
		fprintf(output,"dbg2       etime_i[1]: %d\n",etime_i[1]);
		fprintf(output,"dbg2       etime_i[2]: %d\n",etime_i[2]);
		fprintf(output,"dbg2       etime_i[3]: %d\n",etime_i[3]);
		fprintf(output,"dbg2       etime_i[4]: %d\n",etime_i[4]);
		fprintf(output,"dbg2       etime_i[5]: %d\n",etime_i[5]);
		fprintf(output,"dbg2       etime_i[6]: %d\n",etime_i[6]);
		fprintf(output,"dbg2       speedmin:   %f\n",speedmin);
		fprintf(output,"dbg2       timegap:    %f\n",timegap);
		fprintf(output,"dbg2       file:       %s\n",read_file);
		fprintf(output,"dbg2       mode:       %d\n",mode);
		fprintf(output,"dbg2       gaussian:   %d\n",gaussian);
		fprintf(output,"dbg2       nbins:      %d\n",nbins);
		fprintf(output,"dbg2       nintervals: %d\n",nintervals);
		fprintf(output,"dbg2       value_min:  %f\n",value_min);
		fprintf(output,"dbg2       value_max:  %f\n",value_max);
		}

	/* if help desired then print it and exit */
	if (help)
		{
		fprintf(output,"\n%s\n",help_message);
		fprintf(output,"\nusage: %s\n", usage_message);
		exit(error);
		}

	/* allocate memory for histogram arrays */
	if (error == MB_ERROR_NO_ERROR)
		status = mb_mallocd(verbose,__FILE__,__LINE__,nbins*sizeof(double),
				(void **)&histogram,&error);
	if (error == MB_ERROR_NO_ERROR)
		status = mb_mallocd(verbose,__FILE__,__LINE__,nintervals*sizeof(double),
				(void **)&intervals,&error);

	/* if error initializing memory then quit */
	if (error != MB_ERROR_NO_ERROR)
		{
		mb_error(verbose,error,&message);
		fprintf(output,"\nMBIO Error allocating histogram arrays:\n%s\n",message);
		fprintf(output,"\nProgram <%s> Terminated\n",
			program_name);
		exit(error);
		}

	/* output some information */
	if (verbose > 0)
		{
		fprintf(stderr, "\nNumber of data bins: %d\n", nbins);
		fprintf(stderr, "Minimum value:         %f\n", value_min);
		fprintf(stderr, "Maximum value:         %f\n", value_max);
		if (mode == MBHISTOGRAM_BATH)
			fprintf(stderr, "Working on bathymetry data...\n");
		else if (mode == MBHISTOGRAM_AMP)
			fprintf(stderr, "Working on beam amplitude data...\n");
		else
			fprintf(stderr, "Working on sidescan data...\n");
		}

	/* get size of bins */
	dvalue_bin = (value_max - value_min)/(nbins-1);
	value_bin_min = value_min - 0.5*dvalue_bin;
	value_bin_max = value_max + 0.5*dvalue_bin;

	/* initialize histogram */
	for (i=0;i<nbins;i++)
		histogram[i] = 0;

	/* determine whether to read one file or a list of files */
	if (format < 0)
		read_datalist = MB_YES;

	/* open file list */
	if (read_datalist == MB_YES)
	    {
	    if ((status = mb_datalist_open(verbose,&datalist,
					    read_file,look_processed,&error)) != MB_SUCCESS)
		{
		error = MB_ERROR_OPEN_FAIL;
		fprintf(stderr,"\nUnable to open data list file: %s\n",
			read_file);
		fprintf(stderr,"\nProgram <%s> Terminated\n",
			program_name);
		exit(error);
		}
	    if ((status = mb_datalist_read(verbose,datalist,
			    file,&format,&file_weight,&error))
			    == MB_SUCCESS)
		read_data = MB_YES;
	    else
		read_data = MB_NO;
	    }
	/* else copy single filename to be read */
	else
	    {
	    strcpy(file, read_file);
	    read_data = MB_YES;
	    }

	/* loop over all files to be read */
	while (read_data == MB_YES)
	{

	/* obtain format array location - format id will
		be aliased to current id if old format id given */
	status = mb_format(verbose,&format,&error);

	/* initialize reading the swath sonar data file */
	if ((status = mb_read_init(
		verbose,file,format,pings,lonflip,bounds,
		btime_i,etime_i,speedmin,timegap,
		&mbio_ptr,&btime_d,&etime_d,
		&beams_bath,&beams_amp,&pixels_ss,&error)) != MB_SUCCESS)
		{
		mb_error(verbose,error,&message);
		fprintf(output,"\nMBIO Error returned from function <mb_read_init>:\n%s\n",message);
		fprintf(output,"\nMultibeam File <%s> not initialized for reading\n",file);
		fprintf(output,"\nProgram <%s> Terminated\n",
			program_name);
		exit(error);
		}

	/* allocate memory for data arrays */
	if (error == MB_ERROR_NO_ERROR)
		status = mb_register_array(verbose, mbio_ptr, MB_MEM_TYPE_BATHYMETRY,
						sizeof(char), (void **)&beamflag, &error);
	if (error == MB_ERROR_NO_ERROR)
		status = mb_register_array(verbose, mbio_ptr, MB_MEM_TYPE_BATHYMETRY,
						sizeof(double), (void **)&bath, &error);
	if (error == MB_ERROR_NO_ERROR)
		status = mb_register_array(verbose, mbio_ptr, MB_MEM_TYPE_AMPLITUDE,
						sizeof(double), (void **)&amp, &error);
	if (error == MB_ERROR_NO_ERROR)
		status = mb_register_array(verbose, mbio_ptr, MB_MEM_TYPE_BATHYMETRY,
						sizeof(double), (void **)&bathacrosstrack, &error);
	if (error == MB_ERROR_NO_ERROR)
		status = mb_register_array(verbose, mbio_ptr, MB_MEM_TYPE_BATHYMETRY,
						sizeof(double), (void **)&bathalongtrack, &error);
	if (error == MB_ERROR_NO_ERROR)
		status = mb_register_array(verbose, mbio_ptr, MB_MEM_TYPE_SIDESCAN,
						sizeof(double), (void **)&ss, &error);
	if (error == MB_ERROR_NO_ERROR)
		status = mb_register_array(verbose, mbio_ptr, MB_MEM_TYPE_SIDESCAN,
						sizeof(double), (void **)&ssacrosstrack, &error);
	if (error == MB_ERROR_NO_ERROR)
		status = mb_register_array(verbose, mbio_ptr, MB_MEM_TYPE_SIDESCAN,
						sizeof(double), (void **)&ssalongtrack, &error);

	/* if error initializing memory then quit */
	if (error != MB_ERROR_NO_ERROR)
		{
		mb_error(verbose,error,&message);
		fprintf(output,"\nMBIO Error allocating data arrays:\n%s\n",message);
		fprintf(output,"\nProgram <%s> Terminated\n",
			program_name);
		exit(error);
		}

	/* output information */
	if (error == MB_ERROR_NO_ERROR && verbose > 0)
	    {
	    fprintf(stderr, "\nprocessing file: %s %d\n", file, format);
	    }

	/* initialize counting variables */
	nrec = 0;
	nvalue = 0;

	/* read and process data */
	while (error <= MB_ERROR_NO_ERROR)
		{

		/* read a ping of data */
		status = mb_get(verbose,mbio_ptr,&kind,&pings,
				time_i,&time_d,
				&navlon,&navlat,
				&speed,&heading,
				&distance,&altitude,&sonardepth,
				&beams_bath,&beams_amp,&pixels_ss,
				beamflag,bath,amp,bathacrosstrack,bathalongtrack,
				ss,ssacrosstrack,ssalongtrack,
				comment,&error);

		/* process the pings */
		if (error == MB_ERROR_NO_ERROR
			|| error == MB_ERROR_TIME_GAP)
			{
			/* increment record counter */
			nrec++;

			/* do the bathymetry */
			if (mode == MBHISTOGRAM_BATH)
			for (i=0;i<beams_bath;i++)
				{
				if (mb_beam_ok(beamflag[i]))
					{
					nvalue++;
					j = (bath[i] - value_bin_min)
						/dvalue_bin;
					if (j >= 0 && j < nbins)
						histogram[j]++;
					if (data_first == MB_YES)
						{
						data_min = bath[i];
						data_max = bath[i];
						data_first = MB_NO;
						}
					else
						{
						data_min = MIN(bath[i], data_min);
						data_max = MAX(bath[i], data_max);
						}
					}
				}

			/* do the amplitude */
			if (mode == MBHISTOGRAM_AMP)
			for (i=0;i<beams_amp;i++)
				{
				if (mb_beam_ok(beamflag[i]))
					{
					nvalue++;
					j = (amp[i] - value_bin_min)
						/dvalue_bin;
					if (j >= 0 && j < nbins)
						histogram[j]++;
					if (data_first == MB_YES)
						{
						data_min = amp[i];
						data_max = amp[i];
						data_first = MB_NO;
						}
					else
						{
						data_min = MIN(amp[i], data_min);
						data_max = MAX(amp[i], data_max);
						}
					}
				}

			/* do the sidescan */
			if (mode == MBHISTOGRAM_SS)
			for (i=0;i<pixels_ss;i++)
				{
				if (ss[i] > MB_SIDESCAN_NULL)
					{
					nvalue++;
					j = (ss[i] - value_bin_min)
						/dvalue_bin;
					if (j >= 0 && j < nbins)
						histogram[j]++;
					if (data_first == MB_YES)
						{
						data_min = ss[i];
						data_max = ss[i];
						data_first = MB_NO;
						}
					else
						{
						data_min = MIN(ss[i], data_min);
						data_max = MAX(ss[i], data_max);
						}
					}
				}

			}
		}

	/* close the swath sonar data file */
	status = mb_close(verbose,&mbio_ptr,&error);
	nrectot += nrec;
	nvaluetot += nvalue;

	/* output information */
	if (error == MB_ERROR_NO_ERROR && verbose > 0)
	    {
	    fprintf(stderr, "%d records processed\n%d data processed\n",
		    nrec, nvalue);
	    }

	/* figure out whether and what to read next */
        if (read_datalist == MB_YES)
                {
		if ((status = mb_datalist_read(verbose,datalist,
			    file,&format,&file_weight,&error))
			    == MB_SUCCESS)
                        read_data = MB_YES;
                else
                        read_data = MB_NO;
                }
        else
                {
                read_data = MB_NO;
                }

	/* end loop over files in list */
	}
	if (read_datalist == MB_YES)
		mb_datalist_close(verbose,&datalist,&error);

	/* output information */
	if (error == MB_ERROR_NO_ERROR && verbose > 0)
	    {
	    fprintf(stderr, "\n%d total records processed\n", nrectot);
	    fprintf(stderr, "%d total data processed\n\n", nvaluetot);
	    }

	/* recast histogram as gaussian */
	if (gaussian == MB_YES)
		{
		/* get total number of good values */
		total = 0.0;
		for (i=0;i<nbins;i++)
			total = total + histogram[i];

		/* recast histogram */
		sum = 0.0;
		for (i=0;i<nbins;i++)
			{
			p = (histogram[i]/2 + sum)/(total + 1);
			sum = sum + histogram[i];
			histogram[i] = qsnorm(p);
			}
		}

	/* calculate gaussian intervals if required */
	if (nintervals > 0 && gaussian == MB_YES)
		{
		/* get interval spacing */
		target_min = -2.0;
		target_max = 2.0;
		dinterval = (target_max - target_min)/(nintervals-1);

		/* get intervals */
		intervals[0] = MAX(data_min, value_min);
		intervals[nintervals-1] = MIN(data_max, value_max);
		ibin = 0;
		for (j=1;j<nintervals-1;j++)
			{
			target = target_min + j*dinterval;
			while (histogram[ibin] < target && ibin < nbins-1)
				ibin++;
			if (ibin > 0)
				bin_fraction = 1.0 - (histogram[ibin] - target)
					/(histogram[ibin] - histogram[ibin-1]);
			else
				bin_fraction = 0.0;
			intervals[j] = value_bin_min
					+ dvalue_bin*ibin
					+ bin_fraction*dvalue_bin;
			}
		}

	/* calculate linear intervals if required */
	else if (nintervals > 0)
		{
		/* get total number of good values */
		total = 0.0;
		for (i=0;i<nbins;i++)
			total = total + histogram[i];

		/* get interval spacing */
		dinterval = total/(nintervals-1);

		/* get intervals */
		intervals[0] = value_bin_min;
		total = 0.0;
		ibin = -1;
		for (j=1;j<nintervals;j++)
			{
			target = j*dinterval;
			while (total < target && ibin < nbins-1)
				{
				ibin++;
				total = total + histogram[ibin];
				if (total <= 0.0)
					intervals[0] = value_bin_min
						+ dvalue_bin*ibin;
				}
			bin_fraction = 1.0 - (total - target)/histogram[ibin];
			intervals[j] = value_bin_min
					+ dvalue_bin*ibin
					+ bin_fraction*dvalue_bin;
			}
		}

	/* print out the results */
	if (nintervals <= 0 && gaussian == MB_YES)
		{
		for (i=0;i<nbins;i++)
			{
			fprintf(output,"%f %f\n",
				value_min+i*dvalue_bin,histogram[i]);
			}
		}
	else if (nintervals <= 0)
		{
		for (i=0;i<nbins;i++)
			{
			fprintf(output,"%f %d\n",
				value_min+i*dvalue_bin,(int)histogram[i]);
			}
		}
	else
		{
		for (i=0;i<nintervals;i++)
			fprintf(output,"%f\n",intervals[i]);
		}

	/* deallocate memory used for data arrays */
	mb_freed(verbose,__FILE__,__LINE__,(void **)&histogram,&error);
	mb_freed(verbose,__FILE__,__LINE__,(void **)&intervals,&error);

	/* set program status */
	status = MB_SUCCESS;

	/* check memory */
	if (verbose >= 4)
		status = mb_memory_list(verbose,&error);

	/* print output debug statements */
	if (verbose >= 2)
		{
		fprintf(output,"\ndbg2  Program <%s> completed\n",
			program_name);
		fprintf(output,"dbg2  Ending status:\n");
		fprintf(output,"dbg2       status:  %d\n",status);
		}

	/* end it all */
	fprintf(output,"\n");
	exit(error);
}
Пример #3
0
/*--------------------------------------------------------------------*/
int mbr_wt_hydrob93(int verbose, void *mbio_ptr, void *store_ptr, int *error)
{
	char	*function_name = "mbr_wt_hydrob93";
	int	status = MB_SUCCESS;
	struct mb_io_struct *mb_io_ptr;
	struct mbsys_singlebeam_struct *store;
	char	line[MBF_HYDROB93_RECORD_LENGTH];
	int	ilongitude, ilatitude, idepth;
	short	itype;

	/* print input debug statements */
	if (verbose >= 2)
		{
		fprintf(stderr,"\ndbg2  MBIO function <%s> called\n",function_name);
		fprintf(stderr,"dbg2  Input arguments:\n");
		fprintf(stderr,"dbg2       verbose:    %d\n",verbose);
		fprintf(stderr,"dbg2       mbio_ptr:   %lu\n",(size_t)mbio_ptr);
		fprintf(stderr,"dbg2       store_ptr:  %lu\n",(size_t)store_ptr);
		}

	/* get pointer to mbio descriptor */
	mb_io_ptr = (struct mb_io_struct *) mbio_ptr;

	/* get pointer to raw data structure */
	store = (struct mbsys_singlebeam_struct *) store_ptr;

	/* handle the data */
	if (store->kind == MB_DATA_DATA)
	    {
	    /* print output debug statements */
	    if (verbose >= 4)
		    {
		    fprintf(stderr,"\ndbg4  Data to be written in MBIO function <%s>\n",
			    function_name);
		    fprintf(stderr,"dbg4  Values,read:\n");
		    fprintf(stderr,"dbg4       latitude:     %f\n",store->latitude);
		    fprintf(stderr,"dbg4       longitude:    %f\n",store->longitude);
		    fprintf(stderr,"dbg4       bath:         %f\n",store->bath);
		    fprintf(stderr,"dbg4       flag:         %d\n",store->flag);
		    fprintf(stderr,"dbg4       error:        %d\n",*error);
		    fprintf(stderr,"dbg4       status:       %d\n",status);
		    }
		    
	    /* put data into buffer */
	    ilongitude = (int)(1000000 * store->longitude);
	    ilatitude = (int)(1000000 * store->longitude);
	    idepth = (int)(10 * store->bath);
	    if (mb_beam_ok(store->flag))
	    	itype = 711;
	    else if (store->flag == MB_FLAG_NULL)
	    	itype = 0;
	    else
	    	itype = 10711;
	    mb_put_binary_int(MB_YES, (int) ilatitude, (void *) &line[0]); 
	    mb_put_binary_int(MB_YES, (int) ilongitude, (void *) &line[4]); 
	    mb_put_binary_int(MB_YES, (int) idepth, (void *) &line[8]); 
	    mb_put_binary_short(MB_YES, (short) itype, (void *) &line[12]); 
	    }

	if ((status = fwrite(line,1,MBF_HYDROB93_RECORD_LENGTH,
		mb_io_ptr->mbfp)) == MBF_HYDROB93_RECORD_LENGTH) 
		{
		status = MB_SUCCESS;
		*error = MB_ERROR_NO_ERROR;
		}
	else
		{
		status = MB_FAILURE;
		*error = MB_ERROR_WRITE_FAIL;
		}

	/* print output debug statements */
	if (verbose >= 5)
		{
		fprintf(stderr,"\ndbg5  Data record kind in MBIO function <%s>\n",function_name);
		fprintf(stderr,"dbg5       kind:       %d\n",store->kind);
		}

	/* print output debug statements */
	if (verbose >= 2)
		{
		fprintf(stderr,"\ndbg2  MBIO function <%s> completed\n",function_name);
		fprintf(stderr,"dbg2  Return values:\n");
		fprintf(stderr,"dbg2       error:      %d\n",*error);
		fprintf(stderr,"dbg2  Return status:\n");
		fprintf(stderr,"dbg2       status:  %d\n",status);
		}

	/* return status */
	return(status);
}
Пример #4
0
/*--------------------------------------------------------------------*/
int mbr_wt_em12darw(int verbose, void *mbio_ptr, void *store_ptr, int *error) {
	char *function_name = "mbr_wt_em12darw";
	int status = MB_SUCCESS;
	struct mb_io_struct *mb_io_ptr;
	struct mbf_em12darw_struct *data;
	struct mbsys_simrad_struct *store;
	struct mbsys_simrad_survey_struct *ping;
	char line[MBF_EM12DARW_RECORD_LENGTH];
	int index;
	char *datacomment;
	int time_i[7];
	int time_j[5];
	int year;
	int i;

	/* print input debug statements */
	if (verbose >= 2) {
		fprintf(stderr, "\ndbg2  MBIO function <%s> called\n", function_name);
		fprintf(stderr, "dbg2  Input arguments:\n");
		fprintf(stderr, "dbg2       verbose:    %d\n", verbose);
		fprintf(stderr, "dbg2       mbio_ptr:   %p\n", (void *)mbio_ptr);
		fprintf(stderr, "dbg2       store_ptr:  %p\n", (void *)store_ptr);
	}

	/* get pointer to mbio descriptor */
	mb_io_ptr = (struct mb_io_struct *)mbio_ptr;

	/* get pointer to raw data structure */
	data = (struct mbf_em12darw_struct *)mb_io_ptr->raw_data;
	datacomment = (char *)&line[80];
	store = (struct mbsys_simrad_struct *)store_ptr;

	/* print debug statements */
	if (verbose >= 5) {
		fprintf(stderr, "\ndbg5  Status at beginning of MBIO function <%s>\n", function_name);
		fprintf(stderr, "dbg5       store->kind:    %d\n", store->kind);
		fprintf(stderr, "dbg5       error:          %d\n", *error);
		fprintf(stderr, "dbg5       status:         %d\n", status);
	}

	/*  translate values from em12 data storage structure */
	if (store->kind == MB_DATA_DATA) {
		/* record type */
		data->func = 150;

		/* time */
		time_i[0] = store->year;
		time_i[1] = store->month;
		time_i[2] = store->day;
		time_i[3] = store->hour;
		time_i[4] = store->minute;
		time_i[5] = store->second;
		time_i[6] = store->centisecond;
		mb_get_jtime(verbose, time_i, time_j);
		mb_unfix_y2k(verbose, time_j[0], &year);
		data->year = (short)year;
		data->jday = time_j[1];
		data->minute = time_j[2];
		data->secs = 100 * time_j[3] + 0.0001 * time_j[4];

		/* navigation */
		data->utm_zone = store->utm_zone;
		data->utm_merd = store->utm_zone_lon;
		data->corflag = store->utm_system;
		data->posq = store->pos_quality;
		data->speed = store->speed;
		if (data->corflag == 0) {
			data->latitude = store->pos_latitude;
			data->longitude = store->pos_longitude;
		}
		else {
			data->latitude = store->utm_northing;
			data->longitude = store->utm_easting;
		}

		/* deal with survey data
		    in secondary data structure */
		if (store->ping != NULL) {
			/* get data structure pointer */
			ping = (struct mbsys_simrad_survey_struct *)store->ping;

			/* copy survey data */
			data->latitude = ping->latitude;
			data->longitude = ping->longitude;
			data->pingno = ping->ping_number;
			data->mode = ping->bath_res;
			data->depthl = ping->keel_depth;
			data->gyro = 0.1 * ping->heading;
			data->roll = 0.01 * ping->roll;
			data->pitch = 0.01 * ping->pitch;
			data->heave = 0.01 * ping->ping_heave;
			data->sndval = 0.1 * ping->sound_vel;
			for (i = 0; i < ping->beams_bath; i++) {
				if (ping->beamflag[i] == MB_FLAG_NULL)
					data->depth[i] = 0;
				else if (!mb_beam_ok(ping->beamflag[i]))
					data->depth[i] = -ping->bath[i];
				else
					data->depth[i] = ping->bath[i];
				data->distacr[i] = ping->bath_acrosstrack[i];
				data->distalo[i] = ping->bath_alongtrack[i];
				data->range[i] = ping->tt[i];
				data->refl[i] = (short int)ping->amp[i];
				data->beamq[i] = (short int)ping->quality[i];
			}
		}
	}

	/* comment */
	else if (store->kind == MB_DATA_COMMENT) {
		data->func = 100;
		strncpy(datacomment, store->comment, MBSYS_SIMRAD_COMMENT_LENGTH);
	}

	/* print debug statements */
	if (verbose >= 5) {
		fprintf(stderr, "\ndbg5  Ready to write data in MBIO function <%s>\n", function_name);
		fprintf(stderr, "dbg5       store->kind:       %d\n", store->kind);
		fprintf(stderr, "dbg5       error:             %d\n", *error);
		fprintf(stderr, "dbg5       status:            %d\n", status);
	}

	/* print debug statements */
	if (verbose >= 4 && status == MB_SUCCESS) {
		fprintf(stderr, "\ndbg4  Data to be written by MBIO function <%s>\n", function_name);
		fprintf(stderr, "dbg4  Status values:\n");
		fprintf(stderr, "dbg4       store->kind:%d\n", store->kind);
		fprintf(stderr, "dbg4       error:      %d\n", *error);
		fprintf(stderr, "dbg4       status:     %d\n", status);
		if (store->kind == MB_DATA_DATA) {
			fprintf(stderr, "dbg4  Survey values:\n");
			fprintf(stderr, "dbg4       year:       %d\n", data->year);
			fprintf(stderr, "dbg4       jday:       %d\n", data->jday);
			fprintf(stderr, "dbg4       minute:     %d\n", data->minute);
			fprintf(stderr, "dbg4       secs:       %d\n", data->secs);
			fprintf(stderr, "dbg4       latitude:   %f\n", data->latitude);
			fprintf(stderr, "dbg4       longitude:  %f\n", data->longitude);
			fprintf(stderr, "dbg4       corflag:    %d\n", data->corflag);
			fprintf(stderr, "dbg4       utm_merd:   %f\n", data->utm_merd);
			fprintf(stderr, "dbg4       utm_zone:   %d\n", data->utm_zone);
			fprintf(stderr, "dbg4       posq:       %d\n", data->posq);
			fprintf(stderr, "dbg4       pingno:     %d\n", data->pingno);
			fprintf(stderr, "dbg4       mode:       %d\n", data->mode);
			fprintf(stderr, "dbg4       depthl:     %f\n", data->depthl);
			fprintf(stderr, "dbg4       speed:      %f\n", data->speed);
			fprintf(stderr, "dbg4       gyro:       %f\n", data->gyro);
			fprintf(stderr, "dbg4       roll:       %f\n", data->roll);
			fprintf(stderr, "dbg4       pitch:      %f\n", data->pitch);
			fprintf(stderr, "dbg4       heave:      %f\n", data->heave);
			fprintf(stderr, "dbg4       sndval:     %f\n", data->sndval);
			for (i = 0; i < MBF_EM12DARW_BEAMS; i++)
				fprintf(stderr, "dbg4       beam:%d  depth:%d  distacr:%d  distalo:%d  range:%d refl:%d beamq:%d\n", i,
				        data->depth[i], data->distacr[i], data->distalo[i], data->range[i], data->refl[i], data->beamq[i]);
		}
		else if (store->kind == MB_DATA_COMMENT) {
			fprintf(stderr, "dbg4  Comment:\n");
			fprintf(stderr, "dbg4       comment:    %s\n", datacomment);
		}
	}

	/* deal with comment */
	if (status == MB_SUCCESS && store->kind == MB_DATA_COMMENT) {
		index = 0;
		for (i = 0; i < MBF_EM12DARW_RECORD_LENGTH; i++)
			line[i] = 0;
		mb_put_binary_short(MB_NO, data->func, &line[0]);
		index += 2;
		strncpy(datacomment, store->comment, MBSYS_SIMRAD_COMMENT_LENGTH);
	}

	/* deal with data */
	else if (status == MB_SUCCESS && store->kind == MB_DATA_DATA) {
		index = 0;
		mb_put_binary_short(MB_NO, data->func, &line[0]);
		index += 2;
		mb_put_binary_short(MB_NO, data->year, &line[index]);
		index += 2;
		mb_put_binary_short(MB_NO, data->jday, &line[index]);
		index += 2;
		mb_put_binary_short(MB_NO, data->minute, &line[index]);
		index += 2;
		mb_put_binary_short(MB_NO, data->secs, &line[index]);
		index += 8;
		mb_put_binary_double(MB_NO, data->latitude, &line[index]);
		index += 8;
		mb_put_binary_double(MB_NO, data->longitude, &line[index]);
		index += 8;
		mb_put_binary_short(MB_NO, data->corflag, &line[index]);
		index += 4;
		mb_put_binary_float(MB_NO, data->utm_merd, &line[index]);
		index += 4;
		mb_put_binary_short(MB_NO, data->utm_zone, &line[index]);
		index += 2;
		mb_put_binary_short(MB_NO, data->posq, &line[index]);
		index += 2;
		mb_put_binary_int(MB_NO, data->pingno, &line[index]);
		index += 4;
		mb_put_binary_short(MB_NO, data->mode, &line[index]);
		index += 4;
		mb_put_binary_float(MB_NO, data->depthl, &line[index]);
		index += 4;
		mb_put_binary_float(MB_NO, data->speed, &line[index]);
		index += 4;
		mb_put_binary_float(MB_NO, data->gyro, &line[index]);
		index += 4;
		mb_put_binary_float(MB_NO, data->roll, &line[index]);
		index += 4;
		mb_put_binary_float(MB_NO, data->pitch, &line[index]);
		index += 4;
		mb_put_binary_float(MB_NO, data->heave, &line[index]);
		index += 4;
		mb_put_binary_float(MB_NO, data->sndval, &line[index]);
		index += 4;
		for (i = 0; i < MBF_EM12DARW_BEAMS; i++) {
			mb_put_binary_short(MB_NO, data->depth[i], &line[index]);
			index += 2;
		}
		for (i = 0; i < MBF_EM12DARW_BEAMS; i++) {
			mb_put_binary_short(MB_NO, data->distacr[i], &line[index]);
			index += 2;
		}
		for (i = 0; i < MBF_EM12DARW_BEAMS; i++) {
			mb_put_binary_short(MB_NO, data->distalo[i], &line[index]);
			index += 2;
		}
		for (i = 0; i < MBF_EM12DARW_BEAMS; i++) {
			mb_put_binary_short(MB_NO, data->range[i], &line[index]);
			index += 2;
		}
		for (i = 0; i < MBF_EM12DARW_BEAMS; i++) {
			mb_put_binary_short(MB_NO, data->refl[i], &line[index]);
			index += 2;
		}
		for (i = 0; i < MBF_EM12DARW_BEAMS; i++) {
			mb_put_binary_short(MB_NO, data->beamq[i], &line[index]);
			index += 2;
		}
	}

	/* write next record to file */
	if (store->kind == MB_DATA_DATA || store->kind == MB_DATA_COMMENT) {
		if ((status = fwrite(line, 1, MBF_EM12DARW_RECORD_LENGTH, mb_io_ptr->mbfp)) == MBF_EM12DARW_RECORD_LENGTH) {
			status = MB_SUCCESS;
			*error = MB_ERROR_NO_ERROR;
		}
		else {
			status = MB_FAILURE;
			*error = MB_ERROR_WRITE_FAIL;
		}
	}
	else {
		status = MB_SUCCESS;
		*error = MB_ERROR_NO_ERROR;
		if (verbose >= 5)
			fprintf(stderr, "\ndbg5  No data written in MBIO function <%s>\n", function_name);
	}

	/* print output debug statements */
	if (verbose >= 2) {
		fprintf(stderr, "\ndbg2  MBIO function <%s> completed\n", function_name);
		fprintf(stderr, "dbg2  Return values:\n");
		fprintf(stderr, "dbg2       error:      %d\n", *error);
		fprintf(stderr, "dbg2  Return status:\n");
		fprintf(stderr, "dbg2       status:  %d\n", status);
	}

	return (status);
}
Пример #5
0
int main (int argc, char **argv)
{
	char program_name[] = "MBPS";
	char help_message[] =  "MBPS reads a swath bathymetry data file and creates a postscript 3-d mesh plot";
	char usage_message[] = "mbps [-Iinfile -Fformat -Nnpings -Ppings\n\t-Byr/mo/da/hr/mn/sc -Eyr/mo/da/hr/mn/sc  \n\t-Aalpha -Keta -Dviewdir -Xvertexag \n\t-T\"title\" -Wmetersperinch \n\t-Sspeedmin -Ggap -Ydisplay_stats \n\t-Zdisplay_scales -V -H]";
	extern char *optarg;
	int	errflg = 0;
	int	c;
	int	help = 0;
	int	flag = 0;

	/*ALBERTO definitions */
	int	gap=1;
	double	*xp, *yp;
	double	xl[4], yl[4];
	double	alpha =		ALPHA_DEF;
	double	eta =		ETA_DEF;
	double	ve =		VE_DEF;
	char	viewdir =	VIEWDIR_DEF;
	int	display_stats = MB_YES;
	int	display_scales = MB_YES;
	double	sin_eta, cos_eta;
	double	sin_alpha, cos_alpha;
	double	track_length, xscale, zscale, zscale_inch;
	double	mean_xp=0.0, mean_yp=0.0, min_xp, max_xp, min_yp, max_yp;
	double	scaling, x_off, y_off;
	double	min_z, max_z, range_z, meters_per_inch=(-1.0);
	double	mean_lat=0.0;
	double	mean_lon=0.0;
	double	mean_latmin;
	double	mean_lonmin;
	double	mean_hdg=0.0;
	int	done, mean_knt=0;
	int	orient;
	char	label[100];
	int	a, b, rotate;
	double	x, y, z;

	/* MBIO status variables */
	int	status = MB_SUCCESS;
	int	verbose = 0;
	int	error = MB_ERROR_NO_ERROR;
	char	*message;

	/* MBIO read control parameters */
	int	format;
	int	lonflip;
	double	bounds[4];
	int	btime_i[7];
	int	etime_i[7];
	double	btime_d;
	double	etime_d;
	double	speedmin;
	double	timegap;
	char	file[MB_PATH_MAXLINE];
	int	pings = 1;
	int	beams_bath;
	int	beams_amp;
	int	pixels_ss;
	int	num_pings_max = MBPS_MAXPINGS;

	/* MBIO read values */
	void	*mbio_ptr = NULL;
	int	kind;
	struct ping data[MBPS_MAXPINGS+3];
	int	time_i[7];
	double	time_d;
	double	navlon;
	double	navlat;
	double	speed;
	double	heading;
	double	distance;
	double	altitude;
	double	sonardepth;
	char	*beamflag;
	double	*bath = NULL;
	double	*bathacrosstrack = NULL;
	double	*bathalongtrack = NULL;
	double	*amp = NULL;
	double	*ss = NULL;
	double	*ssacrosstrack = NULL;
	double	*ssalongtrack = NULL;
	char	comment[MB_COMMENT_MAXLINE];
	int	timbeg_i[7];
	int	timend_i[7];
	double	distot = 0.0;
	int	nread;

	char	title[MB_COMMENT_MAXLINE];
	int	forward;
	double	xx, yy, zz;
	double	heading_start, dheading, dheadingx, dheadingy;
	int	i, j, jj, k;
	
	void Polygon_Fill();
	void Good_Polygon();

	/* initialize some time variables */
	for (i=0;i<7;i++)
		{
		timbeg_i[i] = 0;
		timend_i[i] = 0;
		}

	/* get current default values */
	status = mb_defaults(verbose,&format,&pings,&lonflip,bounds,
		btime_i,etime_i,&speedmin,&timegap);

	/* set default input to stdin */
	strcpy (file, "stdin");

	/* process argument list */
	while ((c = getopt(argc, argv, "VvHhF:f:B:b:E:e:S:s:T:t:I:i:A:a:X:x:K:k:D:d:N:n:P:p:W:w:G:g:YyZz")) != -1)
	    switch (c) 
		{
		case 'H':
		case 'h':
			help++;
			break;
		case 'V':
		case 'v':
			verbose++;
			break;
		case 'A':
		case 'a':
			sscanf (optarg, "%lf", &alpha);
			flag++;
			break;
		case 'B':
		case 'b':
			sscanf (optarg,"%d/%d/%d/%d/%d/%d",
				&btime_i[0],&btime_i[1],&btime_i[2],
				&btime_i[3],&btime_i[4],&btime_i[5]);
			btime_i[6] = 0;
			flag++;
			break;
		case 'D':
		case 'd':
			sscanf (optarg, "%c", &viewdir);
			flag++;
			break;
		case 'E':
		case 'e':
			sscanf (optarg,"%d/%d/%d/%d/%d/%d",
				&etime_i[0],&etime_i[1],&etime_i[2],
				&etime_i[3],&etime_i[4],&etime_i[5]);
			etime_i[6] = 0;
			flag++;
			break;
		case 'F':
		case 'f':
			sscanf (optarg,"%d", &format);
			flag++;
			break;
		case 'G':
		case 'g':
			sscanf (optarg, "%d", &gap);
			flag++;
			break;
		case 'I':
		case 'i':
			sscanf (optarg,"%s", file);
			flag++;
			break;
		case 'K':
		case 'k':
			sscanf (optarg, "%lf", &eta);
			flag++;
			break;
		case 'N':
		case 'n':
			sscanf (optarg, "%d", &num_pings_max);
			if (num_pings_max < 2
			    || num_pings_max > MBPS_MAXPINGS) 
			num_pings_max = MBPS_MAXPINGS;
			flag++;
			break;
		case 'P':
		case 'p':
			sscanf (optarg, "%d", &pings);
			flag++;
			break;
		case 'S':
		case 's':
			sscanf (optarg,"%lf", &speedmin);
			flag++;
			break;
		case 'T':
		case 't':
			sscanf (optarg,"%s", title);
			flag++;
			break;
		case 'X':
		case 'x':
			sscanf (optarg, "%lf", &ve);
			flag++;
			break;
		case 'W':
		case 'w':
			sscanf (optarg, "%lf", &meters_per_inch);
			flag++;
			break;
		case 'Y':
		case 'y':
			display_stats = MB_NO;
			flag++;
			break;
		case 'Z':
		case 'z':
			display_scales = MB_NO;
			flag++;
			break;
		case '?':
			errflg++;
			break;
		} /* switch */

		
	/* Process the title of the plot */
	for (i = 1; i < argc; i++) 
		{
		if (argv[i][0] == '-'&& ((argv[i][1]=='T')||(argv[i][1]=='t')) ) {
			strcpy(title,argv[i]);
			title[0]=' ';
			title[1]=' ';
			}
		}

	/* check that otions are allowed */
	if ((viewdir!='P') && (viewdir!='S') && (viewdir!='B') && 
            (viewdir!='p') && (viewdir!='s') && (viewdir!='b'))
		{
		fprintf(stderr,"viewdir must be either P/p (port) S/s (stbd) or B/b (back)\n");
		errflg++;
		}

	/* if error flagged then print it and exit */
	if (errflg) 
		{
		fprintf(stderr,"usage: %s\n", usage_message);
		fprintf(stderr,"\nProgram <%s> Terminated\n",
			program_name);
		error = MB_ERROR_BAD_USAGE;
		exit(error);
		}

	/* print starting message */
	if (verbose == 1 || help) 
		{
		fprintf(stderr,"\nProgram %s\n",program_name);
		fprintf(stderr,"MB-system Version %s\n",MB_VERSION);
		}

	/* print starting debug statements */
	if (verbose >= 2) 
		{
		fprintf(stderr,"\ndbg2  Program <%s>\n",program_name);
		fprintf(stderr,"dbg2  MB-system Version %s\n",MB_VERSION);
		fprintf(stderr,"dbg2  Control Parameters:\n");
		fprintf(stderr,"dbg2       verbose:    %d\n",verbose);
		fprintf(stderr,"dbg2       help:       %d\n",help);
		fprintf(stderr,"dbg2       format:     %d\n",format);
		fprintf(stderr,"dbg2       btime_i[0]: %d\n",btime_i[0]);
		fprintf(stderr,"dbg2       btime_i[1]: %d\n",btime_i[1]);
		fprintf(stderr,"dbg2       btime_i[2]: %d\n",btime_i[2]);
		fprintf(stderr,"dbg2       btime_i[3]: %d\n",btime_i[3]);
		fprintf(stderr,"dbg2       btime_i[4]: %d\n",btime_i[4]);
		fprintf(stderr,"dbg2       btime_i[5]: %d\n",btime_i[5]);
		fprintf(stderr,"dbg2       btime_i[6]: %d\n",btime_i[6]);
		fprintf(stderr,"dbg2       etime_i[0]: %d\n",etime_i[0]);
		fprintf(stderr,"dbg2       etime_i[1]: %d\n",etime_i[1]);
		fprintf(stderr,"dbg2       etime_i[2]: %d\n",etime_i[2]);
		fprintf(stderr,"dbg2       etime_i[3]: %d\n",etime_i[3]);
		fprintf(stderr,"dbg2       etime_i[4]: %d\n",etime_i[4]);
		fprintf(stderr,"dbg2       etime_i[5]: %d\n",etime_i[5]);
		fprintf(stderr,"dbg2       etime_i[6]: %d\n",etime_i[6]);
		fprintf(stderr,"dbg2       speedmin:   %f\n",speedmin);
		fprintf(stderr,"dbg2       file:       %s\n",file);
		}

	/* if help desired then print it and exit */
	if (help) 
		{
		fprintf(stderr,"\n%s\n",help_message);
		fprintf(stderr,"\nusage: %s\n", usage_message);
		exit(error);
		}

	/* get format if required */
	if (format == 0)
		mb_get_format(verbose,file,NULL,&format,&error);

	/* initialize reading the swath file */
	if ((status = mb_read_init(
		verbose,file,format,pings,lonflip,bounds,
		btime_i,etime_i,speedmin,timegap,
		&mbio_ptr,&btime_d,&etime_d,
		&beams_bath,&beams_amp,&pixels_ss,&error)) != MB_SUCCESS) 
		{
		mb_error(verbose,error,&message);
		fprintf(stderr,"\nMBIO Error returned from function <mb_read_init>:\n%s\n",message);
		fprintf(stderr,"\nMultibeam File <%s> not initialized for reading\n",file);
		fprintf(stderr,"\nProgram <%s> Terminated\n",
			program_name);
		exit(error);
		}

	/* initialize values */
	sin_alpha = sin(alpha*DTR);
	cos_alpha = cos(alpha*DTR);
	sin_eta = sin(eta*DTR);
	cos_eta = cos(eta*DTR);
	min_z = 0.0;
	max_z = -9999.0;

	/* allocate memory for data arrays */
	beamflag = NULL;
	bath = NULL;
	bathacrosstrack = NULL;
	bathalongtrack = NULL;
	amp = NULL;
	ss = NULL;
	ssacrosstrack = NULL;
	ssalongtrack = NULL;
	if (error == MB_ERROR_NO_ERROR)
		status = mb_register_array(verbose, mbio_ptr, MB_MEM_TYPE_BATHYMETRY,
						sizeof(char), (void **)&beamflag, &error);
	if (error == MB_ERROR_NO_ERROR)
		status = mb_register_array(verbose, mbio_ptr, MB_MEM_TYPE_BATHYMETRY,
						sizeof(double), (void **)&bath, &error);
	if (error == MB_ERROR_NO_ERROR)
		status = mb_register_array(verbose, mbio_ptr, MB_MEM_TYPE_BATHYMETRY,
						sizeof(double), (void **)&bathacrosstrack, &error);
	if (error == MB_ERROR_NO_ERROR)
		status = mb_register_array(verbose, mbio_ptr, MB_MEM_TYPE_BATHYMETRY,
						sizeof(double), (void **)&bathalongtrack, &error);
	if (error == MB_ERROR_NO_ERROR)
		status = mb_register_array(verbose, mbio_ptr, MB_MEM_TYPE_AMPLITUDE,
						sizeof(double), (void **)&amp, &error);
	if (error == MB_ERROR_NO_ERROR)
		status = mb_register_array(verbose, mbio_ptr, MB_MEM_TYPE_SIDESCAN, 
						sizeof(double), (void **)&ss, &error);
	if (error == MB_ERROR_NO_ERROR)
		status = mb_register_array(verbose, mbio_ptr, MB_MEM_TYPE_SIDESCAN, 
						sizeof(double), (void **)&ssacrosstrack, &error);
	if (error == MB_ERROR_NO_ERROR)
		status = mb_register_array(verbose, mbio_ptr, MB_MEM_TYPE_SIDESCAN, 
						sizeof(double), (void **)&ssalongtrack, &error);
	for (i=0;i<num_pings_max+3;i++) 
		{
		data[i].beams_bath = 0;
		data[i].beamflag = NULL;
		data[i].bath = NULL;
		data[i].bathacrosstrack = NULL;
		data[i].bathalongtrack = NULL;
		data[i].xp = NULL;
		data[i].yp = NULL;
		}  


	/* if error initializing memory then quit */
	if (error != MB_ERROR_NO_ERROR)
		{
		mb_error(verbose,error,&message);
		fprintf(stderr,"\nMBIO Error allocating data arrays:\n%s\n",message);
		fprintf(stderr,"\nProgram <%s> Terminated\n",
			program_name);
		exit(error);
		}

	/* read and process data */
	nread = 0;
	done = MB_NO;
	error = MB_ERROR_NO_ERROR;
	while (done == MB_NO && error <= MB_ERROR_NO_ERROR)
		{
		/* read a ping of data */
		status = mb_get(verbose,mbio_ptr,&kind,&pings,
			time_i,&time_d,
			&navlon,&navlat,
			&speed,&heading,
			&distance,&altitude,&sonardepth,
			&beams_bath,&beams_amp,&pixels_ss,
			beamflag,bath,amp,
			bathacrosstrack,
			bathalongtrack,
			ss,
			ssacrosstrack,
			ssalongtrack,
			comment,&error);
			
		/* only work with survey data */
		if (error == MB_ERROR_NO_ERROR && kind == MB_DATA_DATA)
			{

			/* allocate arrays */
			data[nread].beams_bath = beams_bath;
			status = mb_mallocd(verbose, __FILE__, __LINE__, beams_bath*sizeof(char), (void **)&(data[nread].beamflag), &error);
			status = mb_mallocd(verbose, __FILE__, __LINE__, beams_bath*sizeof(double), (void **)&(data[nread].bath), &error);
			status = mb_mallocd(verbose, __FILE__, __LINE__, beams_bath*sizeof(double), (void **)&(data[nread].bathacrosstrack), &error);
			status = mb_mallocd(verbose, __FILE__, __LINE__, beams_bath*sizeof(double), (void **)&(data[nread].bathalongtrack), &error);
			status = mb_mallocd(verbose, __FILE__, __LINE__, beams_bath*sizeof(double), (void **)&(data[nread].xp), &error);
			status = mb_mallocd(verbose, __FILE__, __LINE__, beams_bath*sizeof(double), (void **)&(data[nread].yp), &error);

			/* copy data to storage arrays */
			for (i=0;i<beams_bath;i++)
				{
				data[nread].beamflag[i] = beamflag[i];
				data[nread].bath[i] = bath[i];
				data[nread].bathacrosstrack[i] = bathacrosstrack[i];
				data[nread].bathalongtrack[i] = bathalongtrack[i];
				data[nread].xp[i] = BAD;
				data[nread].yp[i] = BAD;
				}

			/* ignore time gaps */
			if (error == MB_ERROR_TIME_GAP)
				{
				error = MB_ERROR_NO_ERROR;
				status = MB_SUCCESS;
				}

			/* output error messages */
			if (error == MB_ERROR_COMMENT)
				{
				/* do nothing */
				}
			else if (verbose >= 1 && error < MB_ERROR_NO_ERROR
				&& error >= MB_ERROR_OTHER)
				{
				mb_error(verbose,error,&message);
				fprintf(stderr,"\nNonfatal MBIO Error:\n%s\n",
					message);
				fprintf(stderr,"Time: %d %d %d %d %d %d %d\n",
					time_i[0],time_i[1],time_i[2],
					time_i[3],time_i[4],time_i[5],
					time_i[6]);
				}
			else if (verbose >= 1 && error < MB_ERROR_NO_ERROR)
				{
				mb_error(verbose,error,&message);
				fprintf(stderr,"\nNonfatal MBIO Error:\n%s\n",
					message);
				fprintf(stderr,"Number of good records so far: %d\n",nread);
				}
			else if (verbose >= 1 && error > MB_ERROR_NO_ERROR 
				&& error != MB_ERROR_EOF)
				{
				mb_error(verbose,error,&message);
				fprintf(stderr,"\nFatal MBIO Error:\n%s\n",
					message);
				fprintf(stderr,"Last Good Time: %d %d %d %d %d %d %d\n",
					time_i[0],time_i[1],time_i[2],
					time_i[3],time_i[4],time_i[5],
					time_i[6]);
				}

			/* calculate raw x,y locations for each beam */
			if (status == MB_SUCCESS) 
				{
				/* set initial heading */
				if (nread == 0)
					heading_start = heading;

				/* get heading x and y components */
				dheading = heading - heading_start;
				if (dheading > 360.0)
				    dheading -= 360.0;
				else if (dheading < 0.0)
				    dheading += 360.0;
				dheadingx = sin(DTR * dheading);
				dheadingy = cos(DTR * dheading);

				/* get alongtrack distance in nav */
				distot += distance * 1000.0;	/* distance in meters */

				/* loop over the beams */
				for (j=0; j<beams_bath; j++) 
					{
					if (j >= data[nread].beams_bath)
						{
						data[nread].beamflag[j] = MB_FLAG_NULL;
						data[nread].xp[j] = BAD;
						data[nread].yp[j] = BAD;
						}
					else if (mb_beam_ok(beamflag[j])) 
						{
						xx = dheadingy * bathacrosstrack[j]
						    + dheadingx * bathalongtrack[j];
						yy = distot
						    - dheadingx * bathacrosstrack[j]
						    + dheadingy * bathalongtrack[j];
						zz = -bath[j];
						if (viewdir=='S' || viewdir=='s') 
							{
							data[nread].xp[j] = yy 
							    + xx * sin_eta * cos_alpha;
							data[nread].yp[j] = zz * cos_eta * ve
							    - xx * sin_eta * sin_alpha;
							}
						else if (viewdir=='P' || viewdir=='p') 
							{
							data[nread].xp[j]= -yy 
							    - xx * sin_eta * cos_alpha;
							data[nread].yp[j]= zz * cos_eta * ve
							    + xx * sin_eta * sin_alpha;
							}
						else if (viewdir=='B' || viewdir=='b') 
							{
							data[nread].xp[j] = xx
							    + yy * sin_eta * cos_alpha;
							data[nread].yp[j]= zz * cos_eta * ve
							    + yy * sin_eta * sin_alpha;
							}
						mean_lat += navlat;
						mean_lon += navlon;
						mean_hdg += heading;
						mean_xp += data[nread].xp[j];
						mean_yp += data[nread].yp[j];
						mean_knt++;

						if (-data[nread].bath[j] < min_z) 
						    min_z= -data[nread].bath[j];
						if (-data[nread].bath[j] > max_z) 
						    max_z= -data[nread].bath[j];
						}
					else 
						{
						data[nread].xp[j] = BAD;
						data[nread].yp[j] = BAD;
						}
					} /* for j=0 ... */

				if (nread == 0)
					{
					for (k=0; k<7; k++)
						timbeg_i[k] = time_i[k];
					}
				else
					{
					for (k=0; k<7; k++)
						timend_i[k]=time_i[k];
					}
				}	/* if status==MB_SUCCESS */

			/* increment counters */
			if (error == MB_ERROR_NO_ERROR)
				{
				nread++;
				}
			}

		/* print debug statements */
		if (verbose >= 2) 
			{
			fprintf(stderr,"\ndbg2  Reading loop finished in program <%s>\n",
			program_name);
			fprintf(stderr,"dbg2       status:     %d\n",status);
			fprintf(stderr,"dbg2       error:      %d\n",error);
			fprintf(stderr,"dbg2       nread:      %d\n",nread);
			fprintf(stderr,"dbg2       pings:      %d\n",pings);
			}

		/* test if done */
		if (nread >= num_pings_max
			&& verbose >= 1) 
			{
			fprintf(stderr, "%s: Maximum number of pings [%d] read before end of file reached...\n",
			    program_name, num_pings_max);
			done = MB_YES;
			}
		if (nread >= num_pings_max || error > MB_ERROR_NO_ERROR) 
			{
			done = MB_YES;
			}

		}  /* end of processing data, 1'st while under read/process data */

	/* close the swath file */
	status = mb_close(verbose,&mbio_ptr,&error);

	/* print debug statements */
	if (verbose >= 2) 
		{
		fprintf(stderr,"\ndbg2  Reading loop finished in program <%s>\n",
				program_name);
		fprintf(stderr,"dbg2       status:     %d\n",status);
		fprintf(stderr,"dbg2       error:      %d\n",error);
		fprintf(stderr,"dbg2       nread:      %d\n",nread);
		fprintf(stderr,"dbg2       pings: %d\n",pings);
		}

	/* total track length in m */
	track_length = distot;	
	mean_lat /= mean_knt;
	mean_latmin = fabs(mean_lat - (int) mean_lat) * 60.0;
	mean_lon /= mean_knt;
	mean_lonmin = fabs(mean_lon - (int) mean_lon) * 60.0;
	mean_hdg /= mean_knt;
	mean_xp /= mean_knt;
	mean_yp /= mean_knt;

	/* rescale xp[],yp[] to zero mean; get min and max */
	max_yp = min_yp = max_xp = min_xp = 0.0;
	for (i=0; i<nread; i++) 
		{
		beamflag = data[i].beamflag;
		xp = data[i].xp;
		yp = data[i].yp;
		for (j=0; j<data[i].beams_bath; j++) 
			{
			if (mb_beam_ok(beamflag[j])) 
				{
				yp[j] -= mean_yp;
				xp[j] -= mean_xp;
				min_xp = MIN(min_xp, xp[j]);
				max_xp = MAX(max_xp, xp[j]);
				min_yp = MIN(min_yp, yp[j]);
				max_yp = MAX(max_yp, yp[j]);
				} /* if yp[][] */
			} 	  /* for j */
		} 		  /* for i */

	/* get page orientation, scaling(in/m) factor and startup plot */
	if ((viewdir=='P') || (viewdir=='S') || (viewdir=='p') || (viewdir=='s')) 
		{
		/* Landscape */		
		orient = 0;
		if (meters_per_inch > 0.0) 
			{
			scaling = 1.0 / meters_per_inch;
			x_off = 11. / 2;
			y_off = 8.5 / 2.;
			} 
		else 
			{
			if ( (5.2 / (max_yp - min_yp)) < (8.5 / (max_xp - min_xp)) )
				scaling = (5.2 / (max_yp - min_yp));
			else
				scaling = (8.5 / (max_xp - min_xp));			
			x_off=(-(max_xp + min_xp) * scaling / 2.0) + (11. / 2);
			y_off=(-(max_yp + min_yp) * scaling / 2.0) + (8.5 / 2) - .2;
			}
		} 
	else 
		{
		/* Portrait */		
		orient = 1;
		if (meters_per_inch > 0.0) 
			{
			scaling = 1.0 / meters_per_inch;
			x_off = 8.5 / 2.0;
			y_off = 11. / 2.0;
			} 
		else 
			{
			if ( (8./(max_yp-min_yp))<(6.5/(max_xp-min_xp)) )
				scaling = (8./(max_yp-min_yp));
			else
				scaling = (6.5/(max_xp-min_xp));
			x_off=(-(max_xp+min_xp)*scaling/2.0)+(8.5/2);
			y_off=(-(max_yp+min_yp)*scaling/2.0)+(11./2)-.2;
			}
		}

       /* initialize the Postscript plotting */
#ifdef GMT_MINOR_VERSION
       ps_plotinit_hires(NULL,0,orient,x_off,y_off,1.0,1.0,1,300,1,
               gmtdefs.paper_width, gmtdefs.page_rgb, 
               gmtdefs.encoding.name, 
               GMT_epsinfo (argv[0]));
#else
       ps_plotinit(NULL,0,orient,x_off,y_off,1.0,1.0,1,300,1,
               gmtdefs.paper_width, gmtdefs.page_rgb, 
               gmtdefs.encoding.name, 
               GMT_epsinfo (argv[0]));
#endif
       GMT_echo_command (argc, argv);

	/* now loop over the data in the appropriate order
	    laying down white filled boxes with black outlines
	    wherever the data is good */
	
	if ((viewdir=='S') || (viewdir=='s')) 
		forward = MB_YES;
	else if ((viewdir=='P') || (viewdir=='p')) 
		forward = MB_NO;
	else if ((viewdir=='B') || (viewdir=='b')) 
		{
		if (alpha < 90.0) 
			forward = MB_YES;
		else 
			forward = MB_NO;
		}
	for (j=0;j<beams_bath-1;j++)
		{
		for (i=0;i<nread-1;i++)
			{
			if (forward == MB_YES)
				jj = j;
			else
				jj = beams_bath - 2 - j;
				
			/* make box */
			if (mb_beam_ok(data[i].beamflag[jj])
			    && mb_beam_ok(data[i+1].beamflag[jj])
			    && mb_beam_ok(data[i].beamflag[jj+1])
			    && mb_beam_ok(data[i+1].beamflag[jj+1]))
				{
				xl[0] = scaling * data[i].xp[jj];
				yl[0] = scaling * data[i].yp[jj];
				xl[1] = scaling * data[i+1].xp[jj];
				yl[1] = scaling * data[i+1].yp[jj];
				xl[2] = scaling * data[i+1].xp[jj+1];
				yl[2] = scaling * data[i+1].yp[jj+1];
				xl[3] = scaling * data[i].xp[jj+1];
				yl[3] = scaling * data[i].yp[jj+1];
				ps_polygon(xl,yl,4,rgb_white,1);
				}
			}
		}

	/* titles and such */
	ps_setline(2);	/* set line width */

	if (display_stats == MB_NO) 
		{
		/* plot a title */
		xl[0]=0;
		yl[0]=max_yp*scaling+.6;
		sprintf(label,"%s",title);
		ps_text(xl[0],yl[0],20.,label,0.,6,0);
		} 
	else 
		{
		/* plot a title */
		xl[0]=0;
		yl[0]=max_yp*scaling+1.3;
		sprintf(label,"%s",title);
		ps_text(xl[0],yl[0],20.,label,0.,6,0);

		/*xl[0]-=3.25;*/
		yl[0]-=0.3;
		sprintf(label,"Mean Lat.: %3d@+o@+ %4.1f'   Mean Lon.: %4d@+o @+%4.1f'   Heading: %.1lf@+o @+",(int)mean_lat, mean_latmin, (int)mean_lon, mean_lonmin, mean_hdg);
		ps_text(xl[0],yl[0],15.,label,0.,6,0);

		yl[0]-=0.3;
		sprintf(label,"View Angle: %.1lf@+o @+  V.E.: %.1lfX   Scale: %.0lf m/inch   Track Length: %.1lf km",eta,ve,1.0/scaling,track_length/1000.0);
		ps_text(xl[0],yl[0],15.,label,0.,6,0);

		yl[0]-=0.3;
		sprintf(label,
		"From %.4d/%.2d/%.2d %.2d:%.2d:%.2d   to  %.4d/%.2d/%.2d %.2d:%.2d:%.2d",
		timbeg_i[0],timbeg_i[1],timbeg_i[2],timbeg_i[3],
		timbeg_i[4],timbeg_i[5],timend_i[0],timend_i[1],
		timend_i[2],timend_i[3],timend_i[4],timend_i[5]);
		ps_text(xl[0],yl[0],15.,label,0.,6,0);
		} /* else after if display_stats */


	if (display_scales == MB_YES) 
		{
		/* plot the x-scale */
		xscale=10000;		/* x scale in m */
		if (track_length < 50000) xscale=5000;
		if (track_length < 20000) xscale=2000;
		if (track_length < 10000) xscale=1000;
		xl[0]=xl[1]= (-xscale*scaling/2.0);
		xl[2]=xl[3]= (-xl[0]);
		xl[0]+=2.;xl[1]+=2.;xl[2]+=2.;xl[3]+=2.;
		yl[1]=yl[2]= min_yp*scaling-1.;
		yl[0]=yl[3]= yl[1]+0.1;
	
#ifdef GMT_MINOR_VERSION
		ps_line(xl,yl,4,3,0);
#else
		ps_line(xl,yl,4,3,0,0);
#endif
		sprintf(label,"%.0f km",xscale/1000.0);
		ps_text(xl[0]+.5,yl[0]+.05,15.,label,0.,6,0);

	
		/* plot the z-scale */
		range_z=(max_z-min_z);
		zscale=2000;		/* z scale in m */
		if (range_z < 3000) zscale=1000;
		if (range_z < 1000) zscale=500;
		if (range_z < 500) zscale=200;
		if (range_z < 250) zscale=100;
		zscale_inch= zscale*scaling*cos_eta*ve;
		xl[1]=xl[2]+0.5;
		xl[2]=xl[1];
		xl[0]=xl[3]= xl[1]+.1;
		yl[0]=yl[1]= min_yp*scaling-1.;
		yl[2]=yl[3]= yl[0]+zscale_inch;

#ifdef GMT_MINOR_VERSION
		ps_line(xl,yl,4,3,0);
#else
		ps_line(xl,yl,4,3,0,0);
#endif
		sprintf(label,"%.0f m",zscale);
		ps_text(xl[0]+0.3,yl[0]+zscale_inch/2.0,15.,label,0.,6,0);


		/* plot an arrow in the ship's direction */
		a=0;
		b=beams_bath/2;
		while (!mb_beam_ok(data[a++].beamflag[b])) {}
		xl[0] = data[--a].xp[b];
		yl[0] = data[a].yp[b];
		a = nread - 1;
		while (!mb_beam_ok(data[a--].beamflag[b])) {}
		xl[1] = data[++a].xp[b];
		yl[1] = data[a].yp[b];
		xl[1] = ((xl[1]-xl[0])/distot/2)+.6;
		yl[1] = ((yl[1]-yl[0])/distot/2) + min_yp*scaling-1.;
		xl[0] = 0.+.6; 
		yl[0] = 0.+min_yp*scaling-0.85;
		ps_vector(xl[0],yl[0],xl[1],yl[1],
		    0.01,0.25,0.1,1.0,rgb_black,0);
		ps_text(xl[0]-1.7,yl[0]+.2,15.,"ship heading",0.,1,0);
		ps_text(xl[0]-1.7,yl[0],15.,"direction",0.,1,0);


		/* plot the three axes */
		for (i=0;i<3;i++) 
			{
			xl[0]=0.;	/* point in center of page */
			yl[0]=0.;
			rotate=0;	/* set to 1 if arrow is rotated below */
			if (i==0) 
				{	
				/* x-axis */
				x=1.;
				y=0;	
				z=0;
				} 
			else if (i==1) 
				{
				/* y-axis */
				x=0;	
				y=1.;	
				z=0;
				} 
			else if (i==2) 
				{	
				/* z-axis */
				x=0;
				y=0;	
				z=-1.;
				}

			if (viewdir=='P' || viewdir=='p') 
				{
				xl[1]=-y-x*sin_eta*cos_alpha+xl[0];
				yl[1]= -z*cos_eta+x*sin_eta*sin_alpha+yl[0];
				} 
			else if (viewdir=='B' || viewdir=='b') 
				{
				xl[1]=(x+y*sin_eta*cos_alpha)+xl[0];
				yl[1]=-z*cos_eta+y*sin_eta*sin_alpha+yl[0];
				} 
			else if (viewdir=='S' || viewdir=='s') 
				{
				xl[1]=y+x*sin_eta*cos_alpha+xl[0];
				yl[1]=z*cos_eta-x*sin_eta*sin_alpha+yl[0];
				}

			if (yl[1]<yl[0]) 
				{	
				/* rotate arrows 180 if facing downward */
				xl[1]=-xl[1];
				yl[1]=-yl[1];
				rotate=1;
				}

			xl[0]=(-3.);		/* move arrows from center to lower left corner */
			yl[0]=(min_yp*scaling-1.);
			xl[1]=xl[0]+xl[1];
			yl[1]=yl[0]+yl[1];

			ps_vector(xl[0],yl[0],xl[1],yl[1],
				0.01,0.25,0.1,1.0,rgb_black,0);

			if (i==0&&rotate==0)
				ps_text(xl[1],yl[1]+.15,15.,"x",0.,6,0);
			else if (i==1&&rotate==0)
				ps_text(xl[1],yl[1]+.15,15.,"y",0.,6,0);
			else if (i==2&&rotate==0)
				ps_text(xl[1],yl[1]+.15,15.,"z",0.,6,0);
			else if (i==0&&rotate==1)
				ps_text(xl[1],yl[1]+.15,15.,"-x",0.,6,0);
			else if (i==1&&rotate==1)
				ps_text(xl[1],yl[1]+.15,15.,"-y",0.,6,0);
			else if (i==2&&rotate==1)
				ps_text(xl[1],yl[1]+.15,15.,"z",0.,6,0);

			} /* (i=0;i<3;i++) */
		} /* if display_scales */

	/* end the postscript file */
	ps_plotend(1);
	
	/* deallocate arrays */
	for (i=0;i<nread;i++)
		{
		mb_freed(verbose,__FILE__, __LINE__, (void **)&(data[i].beams_bath), &error);
		mb_freed(verbose,__FILE__, __LINE__, (void **)&(data[i].bath), &error);
		mb_freed(verbose,__FILE__, __LINE__, (void **)&(data[i].bathacrosstrack), &error);
		mb_freed(verbose,__FILE__, __LINE__, (void **)&(data[i].bathalongtrack), &error);
		mb_freed(verbose,__FILE__, __LINE__, (void **)&(data[i].xp), &error);
		mb_freed(verbose,__FILE__, __LINE__, (void **)&(data[i].yp), &error);
		}

	/* check memory */
	if (verbose >= 4)
		status = mb_memory_list(verbose,&error);

	/* print output debug statements */
	if (verbose >= 2)
		{
		fprintf(stderr,"\ndbg2  Program <%s> completed\n",
			program_name);
		fprintf(stderr,"dbg2  Ending status:\n");
		fprintf(stderr,"dbg2       status:  %d\n",status);
		}

	/* end it all */
	exit(error);

}	/* main */