Example #1
0
int main(int argc, char *argv[])
{
	char *baseFile;
	meta_parameters *meta;
	baseline base;
	int   wid, len,		/* Width and Length of input scene    */
		ss, sl;		/* Offsets of input scene in original */
	int x,y;
	double xScale,yScale;
	float percent=5.0;
	
	FILE  *fin, *fout;
	char  szInPhase[255], szInAmp[255], szOutPhase[255], szOutAmp[255];
	float *data;
	double *sflat,*cflat;
	double derampDirection=1.0;/*1.0=forward deramping.  -1.0=backward deramping.*/
	logflag=0;

/* process command line args */
	currArg=1; /* from cla.h in asf.h */
	/* optional args */
	while (currArg < (argc-3)) {
		char *key = argv[currArg++];
		if (strmatch(key,"-log")) {
			CHECK_ARG(1);
			strcpy(logFile,GET_ARG(1));
			fLog = FOPEN(logFile, "a");
			logflag=1;
		}
		else if (strmatch(key,"-backward")) {
			derampDirection = -1.0;
		}
		else {printf("**Invalid option: %s\n",argv[currArg-1]); usage(argv[0]);}
	}
	if ((argc-currArg) < 3) {printf("Insufficient arguments.\n"); usage(argv[0]);}
	/* required args */
	create_name(szInAmp, argv[currArg], "_amp.img");
	create_name(szInPhase, argv[currArg], "_phase.img");
	baseFile = argv[currArg+1];

	asfSplashScreen(argc, argv);
	
	/* Get input scene size and windowing info, check validity */
	meta = meta_read(szInPhase);

	wid = meta->general->sample_count;
	len = meta->general->line_count;
	ss = meta->general->start_sample - 1;
	sl = meta->general->start_line - 1;
	xScale = meta->sar->sample_increment;
	yScale = meta->sar->line_increment;
	
	create_name(szOutAmp,argv[currArg+2],"_amp.img");
	meta_write(meta, szOutAmp);
	create_name(szOutPhase,argv[currArg+2],"_phase.img");
	meta_write(meta, szOutPhase);

	/*Link over ".amp" file, if it exists.*/
	if (fileExists(szInAmp)&&!fileExists(szOutAmp))
	{
		char command[1024];
		sprintf(command,"ln -s %s %s\n", szInAmp, szOutAmp);
		system(command);
	}
	
	/* buffer mallocs, read data file */
	data = (float *)MALLOC(sizeof(float)*wid);
	sflat = (double *)MALLOC(sizeof(double)*wid);
	cflat = (double *)MALLOC(sizeof(double)*wid);
	fin = fopenImage(szInPhase,"rb");
	fout = fopenImage(szOutPhase,"wb");
	
	/* read in CEOS parameters & convert to meters */
	base=read_baseline(baseFile);
	
	/* calculate slant ranges and look angles - Ian's thesis eqn 3.10 */
	for (x = 0; x < wid; x++) {
		double flat=meta_flat(meta,0.0,x*xScale+ss);
		sflat[x]=sin(flat);
		cflat[x]=cos(flat);
	}
	/* Deramp 'data' array */
	
/*	printf("\n  starting in-place deramp of input data \n\n");*/
	for (y = 0; y < len; y++)
	{
		double Bn_y,Bp_y;
		double twok=derampDirection*2.0*meta_get_k(meta);
		meta_interp_baseline(meta,base,y*(int)yScale+sl,&Bn_y,&Bp_y);
		/* read in the next row of data */
		get_float_line(fin, meta, y, data);
		
		/* calculate flat-earth range phase term & remove it */ 
		for (x = 0; x < wid; x++)
		{
			double d=data[x];
			if (d!=0.0) /*Ignore points which didn't phase unwrap.*/
				d -= twok*(Bp_y*cflat[x]-Bn_y*sflat[x]);
			/*Was: d-=ceos_flat_phase(ceos,base,x,y);*/
			data[x]=d;
		}
		
		/* write out this row of data */
		put_float_line(fout, meta, y, data);
		if (y*100/len==percent) {
		  printf("   Completed %3.0f percent\n", percent);
		  percent+=5.0;
		}
	}
/*	printf("\nDone with deramp\n\n");*/
	
	/* save and scram */
	FCLOSE(fin); FCLOSE(fout);
	FREE(data); FREE(sflat);FREE(cflat);

	printf("   Completed 100 percent\n\n");
	if (logflag) {
	  sprintf(logbuf, "   Wrote %lld bytes of data\n\n", (long long)(len*wid*4));
	  printLog(logbuf);
	}

	return 0;
}
Example #2
0
int dem2phase(char *demFile, char *baseFile, char *phaseFile)
{
  int x, y, start_sample, start_line, line_count, sample_count;
  double k, *phase2elevBase, *sinFlat, *cosFlat, xScale, yScale;
  baseline base;
  meta_parameters *meta;
  FILE *fpDem, *fpPhase;
  float *phase,*dem;
  
  meta = meta_read(demFile);
  start_sample = meta->general->start_sample;
  start_line = meta->general->start_line;
  xScale = meta->sar->sample_increment;
  yScale = meta->sar->line_increment;
  line_count = meta->general->line_count;
  sample_count = meta->general->sample_count;
  
  meta_write(meta, phaseFile);
  
  // Allocate some memory
  phase = (float *)MALLOC(sizeof(float)*sample_count);
  dem =(float *)MALLOC(sizeof(float)*sample_count);
 
  // Get wavenumber
  k = meta_get_k(meta);
  
  // Read in baseline values
  base = read_baseline(baseFile);

  // Open files  
  fpDem = fopenImage(demFile, "rb");
  fpPhase = fopenImage(phaseFile,"wb");
  
  /* calculate the sine of the incidence angle across cols*/
  sinFlat = (double *)MALLOC(sizeof(double)*sample_count);
  cosFlat = (double *)MALLOC(sizeof(double)*sample_count);
  phase2elevBase = (double *)MALLOC(sizeof(double)*sample_count);
  for (x=0; x<sample_count; x++) {
    int img_x = x*xScale + start_sample;
    double incid = meta_incid(meta, 0.0, (float)img_x);
    double flat = meta_flat(meta, 0.0, (float)img_x);
    sinFlat[x] = sin(flat);
    cosFlat[x] = cos(flat);
    phase2elevBase[x] = 
      meta_get_slant(meta, 0.0, (float)img_x) * sin(incid)/(2.0*k);
  }
  
  
  // Loop through each row and calculate height
  for (y=0;y<line_count;y++) {
    double Bn_y, Bp_y;
    
    // Read in data 
    get_float_line(fpDem, meta, y, dem);
    
    // Calculate baseline for this row
    meta_interp_baseline(meta, base, y*(int)yScale+start_line, &Bn_y, &Bp_y);
    
    // Step through each pixel in row
    for (x=0; x<sample_count; x++)
      phase[x] = dem[x]/phase2elevBase[x]*(-Bp_y*sinFlat[x]-Bn_y*cosFlat[x]);
    put_float_line(fpPhase, meta, y, phase);
    asfLineMeter(y, line_count);
  }
  asfPrintStatus("Wrote %d lines of simulated phase data.\n\n", line_count);
  
  // Clean up
  FREE(phase);
  FREE(dem);
  FCLOSE(fpPhase);
  FCLOSE(fpDem);

  return(0);
}
Example #3
0
int main(int argc, char **argv)
{
	int x, y;
	int maskflag=0;
	unsigned char *mask;
	double k;
	double *phase2elevBase,*sinFlat,*cosFlat;
	char datafile[256], basefile[256], outfile[256];
	char maskfile[256];
	int nrows,ncols; 
	float *f_coh;
	float *f_eleverr;
	float percent=0.0;
	double init_err=DEFAULT_ERROR;
	FILE *fdata, *fmask, *fout;
	meta_parameters *meta;
	baseline base;


/* Parse command line arguments */
	logflag=FALSE;
	while (currArg < (argc-NUM_ARGS)) {
	   char *key = argv[currArg++];
	   if (strmatch(key,"-log")) {
	      CHECK_ARG(1);
	      strcpy(logFile,GET_ARG(1));
	      fLog = FOPEN(logFile, "a");
	      logflag=TRUE;
	   }
	   else if (strmatch(key, "-mask")) {
	      CHECK_ARG(1);
	      strcpy(maskfile, GET_ARG(1));
	      maskflag = TRUE;
	   }
	   else if (strmatch(key,"-i")) {
	      CHECK_ARG(1);
	      init_err = atof(GET_ARG(1));
	      init_err *= init_err;
	   }
	   else {
	      printf("\n**Invalid option:  %s\n",argv[currArg-1]);
	      usage(argv[0]);
	   }
	}
	if ((argc-currArg) < NUM_ARGS) {
	   printf("Insufficient arguments.\n");
	   usage(argv[0]);
	}

	create_name(datafile, argv[currArg], ".img");
	strcpy(basefile, argv[currArg+1]);
	strcpy(outfile, argv[currArg+2]);

	asfSplashScreen(argc, argv);

/* Get appropriate metadata */
	meta = meta_read(datafile);
	nrows = meta->general->line_count;
	ncols = meta->general->sample_count;
	meta->general->data_type = REAL32;
	meta_write(meta, outfile);
	k  = meta_get_k(meta);    /* wave number*/
	
/* Allocate space for vectors, matricies, and stuff*/
	mask = (unsigned char *)MALLOC(sizeof(unsigned char)*ncols);
	f_coh = (float *)MALLOC(sizeof(float)*ncols);
	f_eleverr = (float *)MALLOC(sizeof(float)*ncols);
	sinFlat = (double *)MALLOC(sizeof(double)*ncols);
	cosFlat = (double *)MALLOC(sizeof(double)*ncols);
	phase2elevBase = (double *)MALLOC(sizeof(double)*ncols);

/* Open data file & get seed phase*/
	fdata = fopenImage(datafile, "rb");
	fout = fopenImage(outfile,"wb");
	if (maskflag) fmask = fopenImage(maskfile,"rb");
	
/* Read in baseline values*/
	base = read_baseline(basefile);

/* Obtain information from metadata*/
	for (x=0;x<ncols;x++)
	{
		int img_x = x * meta->sar->sample_increment
		            + meta->general->start_sample;
		double incid=meta_incid(meta,0,img_x);
		double flat=meta_flat(meta,0,img_x);
		sinFlat[x]=sin(flat);
		cosFlat[x]=cos(flat);
		phase2elevBase[x]=meta_get_slant(meta,0,img_x)*sin(incid)/(2.0*k);
	}

/* Loop through each row & calculate height*/
	for (y=0;y<nrows;y++) {
		double Bn_y,Bp_y;

		/* Report progress */
		if ((y*100/nrows)>percent) {
		  printf("\r   Completed %3.0f percent", percent);
		  fflush(NULL);
		  percent+=5.0;
		}

		/* read in data */
		if (maskflag)
			ASF_FREAD(mask,sizeof(unsigned char),ncols,fmask);
		get_float_line(fdata, meta, y, f_coh);
		
		/* calculate baseline for this row*/
		meta_interp_baseline(meta, base,
			y*meta->sar->line_increment+meta->general->start_line+1,
			&Bn_y, &Bp_y);
		
		/* step through each pixel in row*/
		for (x=0;x<ncols;x++) {
			if ((mask[x] == 0x10 && maskflag) || (!maskflag)) {
				double tmp,tmp1,sigma_height;
				tmp = phase2elevBase[x]/(-Bp_y*sinFlat[x]-Bn_y*cosFlat[x]);
				tmp1 = (FLOAT_EQUALS_ZERO(f_coh[x])) 
					    ? 0.0 : sqrt((1-f_coh[x])/f_coh[x]);
				sigma_height = tmp*tmp1;
				f_eleverr[x] = (float)sqrt( init_err +
					sigma_height*sigma_height );
			}
			else
				f_eleverr[x] = -1.0;
		}
		put_float_line(fout, meta, y, f_eleverr);
	}
	printf("\r   Completed 100 percent\n\n");
	sprintf(logbuf, "   Wrote %lld bytes of data\n\n",
	        (long long)(nrows*ncols*4));
	printf("%s", logbuf);
	if (logflag) { printLog(logbuf); }
	
	/* free memory & scram*/
	meta_free(meta);
	FREE(mask);
	FREE(f_coh);
	FREE(f_eleverr);
	FREE(sinFlat);
	FREE(cosFlat);
	FREE(phase2elevBase);
	FCLOSE(fdata);
	FCLOSE(fout);
	if (maskflag) FCLOSE(fmask);

	exit(EXIT_SUCCESS);
}
Example #4
0
/*
 * routine:
 *	main
 *
 * purpose:
 *	argument processing and primary dispatch
 *
 * returns:
 *	error codes per filesync.1 (ERR_* in filesync.h)
 *
 * notes:
 *	read filesync.1 in order to understand the argument processing
 *
 *	most of the command line options just set some opt_ global
 *	variable that is later looked at by the code that actually
 *	implements the features.  Only file names are really processed
 *	in this routine.
 */
int
main(int argc, char **argv)
{	int i;
	int c;
	errmask_t errs = ERR_OK;
	int do_prune = 0;
	char *srcname = 0;
	char *dstname = 0;
	struct base *bp;

	/* keep the error messages simple	*/
	argv[0] = "filesync";

	/* gather together all of the options	*/
	while ((c = getopt(argc, argv, "AaehmnqvyD:E:r:s:d:f:o:")) != EOF)
		switch (c) {
			case 'a':	/* always scan for acls	*/
				opt_acls = TRUE;
				break;
			case 'e':	/* everything agrees	*/
				opt_everything = TRUE;
				break;
			case 'h':	/* halt on error	*/
				opt_halt = TRUE;
				break;
			case 'm':	/* preserve modtimes	*/
				opt_mtime = TRUE;
				break;
			case 'n':	/* notouch		*/
				opt_notouch = TRUE;
				break;
			case 'q':	/* quiet		*/
				opt_quiet = TRUE;
				break;
			case 'v':	/* verbose		*/
				opt_verbose = TRUE;
				break;
			case 'y':	/* yes			*/
				opt_yes = TRUE;
				break;
			case 'D':	/* debug options	*/
				if (!isdigit(optarg[0])) {
					dbg_usage();
					exit(ERR_INVAL);
				}
				opt_debug |= strtol(optarg, (char **)NULL, 0);
				break;

			case 'E':	/* error simulation	*/
				if (dbg_set_error(optarg)) {
					err_usage();
					exit(ERR_INVAL);
				}
				opt_errors = TRUE;
				break;

			case 'f':	/* force conflict resolution	*/
				switch (optarg[0]) {
					case 's':
						opt_force = OPT_SRC;
						break;
					case 'd':
						opt_force = OPT_DST;
						break;
					case 'o':
						opt_force = OPT_OLD;
						break;
					case 'n':
						opt_force = OPT_NEW;
						break;
					default:
						fprintf(stderr,
							gettext(ERR_badopt),
							c, optarg);
						errs |= ERR_INVAL;
						break;
				}
				break;

			case 'o':	/* one way propagation		*/
				switch (optarg[0]) {
					case 's':
						opt_oneway = OPT_SRC;
						break;
					case 'd':
						opt_oneway = OPT_DST;
						break;
					default:
						fprintf(stderr,
							gettext(ERR_badopt),
							c, optarg);
						errs |= ERR_INVAL;
						break;
				}
				break;

			case 'r':	/* restricted reconciliation	*/
				if (num_restrs < MAX_RLIST)
					rlist[ num_restrs++ ] = optarg;
				else {
					fprintf(stderr, gettext(ERR_tomany),
						MAX_RLIST);
					errs |= ERR_INVAL;
				}
				break;

			case 's':
				if ((srcname = qualify(optarg)) == 0)
					errs |= ERR_MISSING;
				break;

			case 'd':
				if ((dstname = qualify(optarg)) == 0)
					errs |= ERR_MISSING;
				break;

			default:
			case '?':
				errs |= ERR_INVAL;
				break;
		}

	if (opt_debug & DBG_MISC)
		fprintf(stderr, "MISC: DBG=%s\n", showflags(dbgmap, opt_debug));

	/* if we have file names, we need a source and destination */
	if (optind < argc) {
		if (srcname == 0) {
			fprintf(stderr, gettext(ERR_nosrc));
			errs |= ERR_INVAL;
		}
		if (dstname == 0) {
			fprintf(stderr, gettext(ERR_nodst));
			errs |= ERR_INVAL;
		}
	}

	/* check for simple usage errors	*/
	if (errs & ERR_INVAL) {
		usage();
		exit(errs);
	}

	/* locate our baseline and rules files	*/
	if (c = findfiles())
		exit(c);

	/* figure out file creation defaults	*/
	whoami();

	/* read in our initial baseline		*/
	if (!new_baseline && (c = read_baseline(file_base)))
		errs |= c;

	/* read in the rules file if we need or have rules	*/
	if (optind >= argc && new_rules) {
		fprintf(stderr, ERR_nonames);
		errs |= ERR_INVAL;
	} else if (!new_rules)
		errs |= read_rules(file_rules);

	/* if anything has failed with our setup, go no further	*/
	if (errs) {
		cleanup(errs);
		exit(errs);
	}

	/*
	 * figure out whether or not we are willing to do a one-sided
	 * analysis (where we don't even look at the other side.  This
	 * is an "I'm just curious what has changed" query, and we are
	 * only willing to do it if:
	 *	we aren't actually going to do anything
	 *	we have a baseline we can compare against
	 * otherwise, we are going to insist on being able to access
	 * both the source and destination.
	 */
	if (opt_notouch && !new_baseline)
		opt_onesided = opt_oneway;

	/*
	 * there are two interested usage scenarios:
	 *	file names specified
	 *		create new rules for the specified files
	 *		evaulate and reconcile only the specified files
	 *	no file names specified
	 *		use already existing rules
	 *		consider restricting them to specified subdirs/files
	 */
	if (optind < argc) {
		/* figure out what base pair we're working on	*/
		bp = add_base(srcname, dstname);

		/* perverse default rules to avoid trouble	*/
		if (new_rules) {
			errs |= add_ignore(0, SUFX_RULES);
			errs |= add_ignore(0, SUFX_BASE);
		}

		/* create include rules for each file/dir arg	*/
		while (optind < argc)
			errs |= add_include(bp, argv[ optind++ ]);

		/*
		 * evaluate the specified base on each side,
		 * being careful to limit evaulation to new rules
		 */
		errs |= evaluate(bp, OPT_SRC, TRUE);
		errs |= evaluate(bp, OPT_DST, TRUE);
	} else {
		/* note any possible evaluation restrictions	*/
		for (i = 0; i < num_restrs; i++)
			errs |= add_restr(rlist[i]);

		/*
		 * we can only prune the baseline file if we have done
		 * a complete (unrestricted) analysis.
		 */
		if (i == 0)
			do_prune = 1;

		/* evaulate each base on each side		*/
		for (bp = bases; bp; bp = bp->b_next) {
			errs |= evaluate(bp, OPT_SRC, FALSE);
			errs |= evaluate(bp, OPT_DST, FALSE);
		}
	}

	/* if anything serious happened, skip reconciliation	*/
	if (errs & ERR_FATAL) {
		cleanup(errs);
		exit(errs);
	}

	/* analyze and deal with the differenecs		*/
	errs |= analyze();

	/* see if there is any dead-wood in the baseline	*/
	if (do_prune) {
		c = prune();

		if (c > 0 && opt_verbose)
			fprintf(stdout, V_prunes, c);
	}

	/* print out a final summary				*/
	summary();

	/* update the rules and baseline files (if needed)	*/
	(void) umask(my_umask);
	errs |= write_baseline(file_base);
	errs |= write_rules(file_rules);

	if (opt_debug & DBG_MISC)
		fprintf(stderr, "MISC: EXIT=%s\n", showflags(errmap, errs));

	/* just returning ERR_RESOLVABLE upsets some people	*/
	if (errs == ERR_RESOLVABLE && !opt_notouch)
		errs = 0;

	/* all done	*/
	cleanup(0);
	return (errs);
}
Example #5
0
int asf_elevation(char *unwrapped_phase, char *phase_mask, 
		  char *baseFile, char *seeds, char *slant_elevation,
		  char *slant_elevation_error, char *slant_amplitude, 
		  char *slant_coherence, char *ground_elevation, 
		  char *ground_elevation_error, char *ground_amplitude, 
		  char *ground_coherence)
{

  int x, y, ss, sl, nrows, ncols;
  double xScale, yScale, k, *phase2elevBase, *sinFlat, *cosFlat;
  meta_parameters *meta;
  baseline base;
  FILE *fphase, *felev, *feleverr, *fseed, *fmask, *fcoh;
  float *uwp, *coh, *elev, *eleverr;
  unsigned char *mask;
  double delta_phase, delta_height;
  double seed_phase, seed_height;

  printf("\nGenerating slant range elevation and elevation error ...\n\n");

  /* Get input scene size and windowing info. Get datafile values*/
  meta = meta_read(unwrapped_phase);
  nrows  = meta->general->line_count;
  ncols  = meta->general->sample_count;
  sl     = meta->general->start_line;
  ss     = meta->general->start_sample;
  yScale = meta->sar->look_count;
  xScale = meta->sar->sample_increment;
  
  // Write metadata files for temporary slant range images
  //  meta->general->image_data_type = DEM;
  meta_write(meta, slant_elevation);
  meta_write(meta, slant_elevation_error);
  
  /* Allocate space for vectors and matricies*/
  uwp = (float *) MALLOC(sizeof(float)*ncols);
  coh = (float *) MALLOC(sizeof(float)*ncols);
  elev = (float *) MALLOC(sizeof(float)*ncols);
  eleverr = (float *) MALLOC(sizeof(float)*ncols);
  mask = (unsigned char *) MALLOC(sizeof(unsigned char)*ncols);

  // Wavenumber K
  k = meta_get_k(meta);

  // Read in baseline values
  base = read_baseline(baseFile);
  
  // Open input files
  fphase = fopenImage(unwrapped_phase, "rb");
  fseed = FOPEN(seeds, "r");
  fmask = fopenImage(phase_mask, "rb");
  fcoh = fopenImage(slant_coherence, "rb");
  
  /*Use least-squares fit to determine the optimal seed_phase and seed_height.*/
  {
    double x,xSum=0,xSqrSum=0,hSum=0,hxSum=0,pxSum=0,pxSqrSum=0;
    double a,b,c,d,e,f,det;
    int npts=0;
    float *phase_line;
    
    phase_line = (float *) MALLOC(sizeof(float)*meta->general->sample_count);
    
    while (1)
      {
	float seed_x,seed_y,height,phase;
	int seek_x,seek_y;
	/*Read in each seed point*/
	if (3!=fscanf(fseed,"%f%f%f",&seed_x,&seed_y,&height))
	  break;/*Break out when no more points.*/
	seek_x=(int)((seed_x-ss)/xScale);
	seek_y=(int)((seed_y-sl)/yScale);
	get_float_line(fphase, meta, seek_y, phase_line);
	phase = phase_line[seek_y];
	if (phase==0)
	  continue;/*Escher couldn't unwrap this tie point.*/
	
	// Calculate that seed point's impact on fit.
	x         = meta_phase_rate(meta,base,seed_y,seed_x);
	xSum     += x;
	xSqrSum  += x * x;
	hSum     += height;
	hxSum    += height * x;
	pxSum    += phase * x;
	pxSqrSum += phase * x * x;
	npts++;
      }
    if (!quietflag)
      printf("   Read %d seed points\n",npts);
    /* The least-squares fit above leaves us with a matrix equation
     *	[ a  b ]   [ seed_phase  ]   [ e ]
     *	[      ] * [             ] = [   ]
     *	[ c  d ]   [ seed_height ]   [ f ]
     *
     *	which has the solution
     *
     *	[ d  -b ]   [ e ]    1    [ seed_phase  ]
     *	[       ] * [   ] * --- = [             ]
     *	[ -c  a ]   [ f ]   det   [ seed_height ]
     */
    a = -xSqrSum;
    b = xSum;
    c = -xSum;
    d = npts;
    e = hxSum-pxSqrSum;
    f = hSum-pxSum;
    det = a*d-b*c;
    seed_phase  = (e*d-f*b)/det;
    seed_height = (e*(-c)+f*a)/det;
  }
  
  if (!quietflag) 
    printf("   Seed Phase: %f\n   Elevation: %f\n\n",seed_phase,seed_height);
  
  /* calculate the sine of the incidence angle across cols*/
  sinFlat = (double *)MALLOC(sizeof(double)*ncols);
  cosFlat = (double *)MALLOC(sizeof(double)*ncols);
  phase2elevBase = (double *)MALLOC(sizeof(double)*ncols);
  for (x=0;x<ncols;x++)
    {
      int img_x = x*xScale + ss;
      double incid = meta_incid(meta, 0, img_x);
      double flat = meta_flat(meta, 0, img_x);
      sinFlat[x] = sin(flat);
      cosFlat[x] = cos(flat);
      phase2elevBase[x] = meta_get_slant(meta, 0, img_x)*sin(incid)/(2.0*k);
    }
  
  // Open intermediate output files
  felev = fopenImage(slant_elevation, "wb");
  feleverr = fopenImage(slant_elevation_error, "wb");
  
  /* loop through each row & calculate height*/
  /*Note:
    To make this faster, we don't call 
    delta_height=delta_phase * meta_phase_rate(ceos,base,y*yScale+sl,x*xScale+ss).
    Instead, we use the annoying temporary arrays
    allocated above to calculate the same thing, quicker.
  */
  for (y=0; y<nrows; y++) {
    double Bn_y,Bp_y;

    // Read in data
    FREAD(mask, sizeof(unsigned char), ncols, fmask);
    get_float_line(fphase, meta, y, uwp);
    get_float_line(fcoh, meta, y, coh);
    
    // Calculate baseline for this row
    meta_interp_baseline(meta, base, y*yScale+sl+1, &Bn_y, &Bp_y);
    
    // Step through each pixel in row
    for (x=0; x<ncols; x++) {
      // Calculate elevation
      if (uwp[x] != 0.0) {
	delta_phase = (double) uwp[x] - seed_phase;
	delta_height = delta_phase * phase2elevBase[x]/
	  (-Bp_y*sinFlat[x] - Bn_y*cosFlat[x]);
	elev[x] = delta_height + seed_height;
      }
      else 
	elev[x] = 0.0;
      // Calculate elevation error
      if (mask[x] == 0x10) {
	double coh_factor, base_height, sigma_height;
	coh_factor = (FLOAT_EQUALS_ZERO(coh[x])) ? 0.0 : sqrt((1-coh[x])/coh[x]);
	base_height = phase2elevBase[x]/(-Bp_y*sinFlat[x] - Bn_y*cosFlat[x]);
	sigma_height = base_height * coh_factor;
	eleverr[x] = (float) fabs(base_height*coh_factor);
      }
      else
	eleverr[x] = -1.0;
    }
    
    put_float_line(felev, meta, y, elev);
    put_float_line(feleverr, meta, y, eleverr);

    asfLineMeter(y, nrows);
  }
  
  // Free memory and close files
  FREE(uwp);
  FREE(mask);
  FREE(coh);
  FREE(elev);
  FREE(eleverr);
  FREE(sinFlat);
  FREE(cosFlat);
  FREE(phase2elevBase);
  FCLOSE(felev);
  FCLOSE(feleverr);
  FCLOSE(fphase);
  FCLOSE(fseed);
  FCLOSE(fmask);


  int fill_value=-1;
  // Transform all the slant range products into ground range
  printf("\nGenerating ground range elevation ...\n");
  deskew_dem(slant_elevation, NULL, ground_elevation, NULL, 0, NULL, NULL, TRUE,
             fill_value, 0);
  printf("\nGenerating ground range amplitude image ...\n");
  deskew_dem(slant_elevation, NULL, ground_amplitude, slant_amplitude, 1, NULL, NULL,
             TRUE, fill_value, 0);
  printf("\nGenerating ground range elevation error ...\n");
  deskew_dem(slant_elevation, NULL, ground_elevation_error, slant_elevation_error, 1,
             NULL, NULL, TRUE, fill_value, 0);
  printf("\nGenerating ground range coherence image ...\n\n");
  deskew_dem(slant_elevation, NULL, ground_coherence, slant_coherence, 0, NULL, NULL,
             TRUE, fill_value, 0);

  //meta_free(meta);
  return 0;
}