/********************************************************** * meta_incid: Returns the incidence angle * This is the angle measured by the target between straight * up and the satellite. Returns radians.*/ double meta_incid(meta_parameters *meta,double y,double x) { // No effort has been made to make this routine work with // pseudoprojected images. if (strcmp_case(meta->general->sensor, "UAVSAR") == 0) // placeholder for incidence angle information, most likely coming from // a band in the image file return 0.0; else assert (meta->projection == NULL || meta->projection->type != LAT_LONG_PSEUDO_PROJECTION); double sr = meta_get_slant(meta,y,x); if (meta_uses_incid_polynomial(meta)) { // Use the incidence angle polynomial if it is available and non-zero. double R = sr/1000.; double R2=R*R; return meta->sar->incid_a[0] + meta->sar->incid_a[1] * R + meta->sar->incid_a[2] * R2 + meta->sar->incid_a[3] * R2 * R + meta->sar->incid_a[4] * R2 * R2 + meta->sar->incid_a[5] * R2 * R2 * R; } else { double er = meta_get_earth_radius(meta,y,x); double ht = meta_get_sat_height(meta,y,x); return PI-acos((SQR(sr) + SQR(er) - SQR(ht)) / (2.0*sr*er)); } }
static double map_gr2sr(meta_parameters *meta, double l, double s) { double ht = meta_get_sat_height(meta, l, s); double er = meta_get_earth_radius(meta, l, s); double srfp = meta_get_slant(meta, l, 0); double grfp = er * acos((ht*ht+er*er-srfp*srfp)/(2.*ht*er)); double grcp = grfp + s * meta->transform->target_pixel_size; double srcp = sqrt(ht*ht+er*er-2.*ht*er*cos(grcp/er)); return (srcp - srfp)/meta->transform->source_pixel_size; }
/********************************************************** * meta_look: Return the look angle * This is the angle measured by the satellite between * earth's center and the target point x. Returns radians*/ double meta_look(meta_parameters *meta,double y,double x) { // No effort has been made to make this routine work with // pseudoprojected images. assert (meta->projection == NULL || meta->projection->type != LAT_LONG_PSEUDO_PROJECTION); double sr = meta_get_slant(meta,y,x); double er = meta_get_earth_radius(meta,y,x); double ht = meta_get_sat_height(meta,y,x); return acos((SQR(sr) + SQR(ht) - SQR(er)) / (2.0*sr*ht)); }
static double map_sr2gr(meta_parameters *meta, double l, double s) { double ht = meta_get_sat_height(meta, l, s); double srfp = meta_get_slant(meta, l, 0); double er = meta_get_earth_radius(meta, l, s); double x = 1. + (ht - er)/er; double y0 = srfp / er; double grfp = er * acos((1. + x*x - y0*y0)/(2.*x)); double srcp = srfp + s*meta->transform->source_pixel_size; double y1 = srcp/er; double grcp = er*acos((1. + x*x - y1*y1)/(2.*x)); return (grcp - grfp)/meta->transform->target_pixel_size; }
double meta_phase_rate(meta_parameters *meta,const baseline base,int y,int x) { // No effort has been made to make this routine work with // pseudoprojected images. assert (meta->projection == NULL || meta->projection->type != LAT_LONG_PSEUDO_PROJECTION); double sr=meta_get_slant(meta,y,x); double flat=meta_flat(meta,y,x); double incid=meta_incid(meta,y,x); double Bn_y,Bp_y; meta_interp_baseline(meta,base,y,&Bn_y,&Bp_y); /*Note: this is the slant range times sin of the incidence angle, divided by the derivative of meta_flat_phase.*/ return (sr*sin(incid))/(2.0*meta_get_k(meta)*(-Bp_y*sin(flat)-Bn_y*cos(flat))); }
void scan_to_latlon(meta_parameters *meta, double x, double y, double z, double *lat_d, double *lon, double *height) { double qlat, qlon; double lat,radius; vector pos; meta_projection *proj = meta->projection; if (z != 0.0) { // height correction applies directly to y (range direction) double line, samp; line = (y-proj->startY)/proj->perY - meta->general->start_line; samp = (x-proj->startX)/proj->perX - meta->general->start_sample; double sr = meta_get_slant(meta,line,samp); double er = proj->param.atct.rlocal; double ht = meta_get_sat_height(meta,line,samp); double cos_ang = (sr*sr + er*er - ht*ht)/(2.0*sr*er); if (cos_ang > 1) cos_ang = 1; if (cos_ang < -1) cos_ang = -1; double incid = PI-acos(cos_ang); x += z*tan(PI/2-incid); } if (meta->sar->look_direction=='R') qlat = -x/proj->param.atct.rlocal; /* Right looking sar */ else qlat = x/proj->param.atct.rlocal; /* Left looking sar */ qlon = y/(proj->param.atct.rlocal*cos(qlat)); sph2cart(proj->param.atct.rlocal, qlat, qlon, &pos); rotate_z(&pos,-proj->param.atct.alpha3); rotate_y(&pos,-proj->param.atct.alpha2); rotate_z(&pos,-proj->param.atct.alpha1); cart2sph(pos,&radius,&lat,lon); *lon *= R2D; lat *= R2D; *lat_d = atand(tand(lat) / (1-ecc2(proj->re_minor,proj->re_major))); *height = z; // FIXME: Do we need to correct the height at all? }
/******************************************************************* * meta_get_timeSlantDop: * Converts a given line and sample in image into time, slant-range, * and doppler. Works with all image types.*/ void meta_get_timeSlantDop(meta_parameters *meta, double yLine,double xSample,double *time,double *slant,double *dop) { // No effort has been made to make this routine work with // pseudoprojected images. assert (meta->projection == NULL || meta->projection->type != LAT_LONG_PSEUDO_PROJECTION); if (meta->transform) { double lat,lon; meta_get_latLon(meta,yLine,xSample,0.0,&lat,&lon); latLon2timeSlant(meta,lat,lon,time,slant,dop); } // just for testing else if (meta->sar->image_type=='S'||meta->sar->image_type=='G') { /*Slant or ground range. These are easy.*/ *slant = meta_get_slant(meta,yLine,xSample); *time = meta_get_time(meta,yLine,xSample); if (dop != NULL) { if (meta->sar->deskewed == 1) *dop=0.0; else *dop=meta_get_dop(meta,yLine,xSample); } } else if (meta->sar->image_type=='P' || meta->sar->image_type=='R') { double lat,lon; meta_get_latLon(meta,yLine,xSample,0.0,&lat,&lon); latLon2timeSlant(meta,lat,lon,time,slant,dop); } else { /*Bogus image type.*/ printf("Error! Invalid image type '%c' passed to meta_get_timeSlantDop!\n", meta->sar->image_type); exit(1); } }
static void gr2sr_vec(meta_parameters *meta, float srinc, float *gr2sr, int apply_pp_earth_radius_fix) { int i; /* Counter */ float r_sc; /* radius from center of the earth for satellite */ float r_earth; /* radius of the earth */ float r_close; /* near slant range distance */ float rg0, rg; /* Ground range to first pixel, G.R. to cur pix */ float a, x, x2, y; /* temporaries */ float grinc; /* Slant and Ground range pixel spacings */ float rslant; /* slant range distance to current pixel */ /* Radius from the center of the earth to the spacecraft, slant range to first pixel, and radius of the earth */ r_sc = meta_get_sat_height(meta, 0, 0); r_close = meta_get_slant(meta,0,0); if (apply_pp_earth_radius_fix) r_earth = meta_get_earth_radius_pp(meta); else r_earth = meta_get_earth_radius(meta,0,0); /* Set the ground range and slant range increments */ grinc = meta->general->x_pixel_size; /* calculate ground range to first point */ a = (r_sc-r_earth)/r_earth; x = 1.0+a; x2 = x * x; y = r_close/r_earth; rg0 = r_earth * acos((1.0 + x2 - y*y) / (2.0*x)); /* begin loop */ for(i = 0; i<MAX_IMG_SIZE; i++) { rslant = r_close + i *srinc; y = rslant/r_earth; rg = r_earth*acos((1.0+x2-y*y)/(2.0*x)); gr2sr[i] = (rg - rg0)/grinc; } }
static void sr2gr_vec(meta_parameters *meta, float srinc, float newSize, float *sr2gr) { double rg,rg0;/*Ground range distances from nadir, along curve of earth.*/ double ht,re,sr;/*S/C height, earth radius, slant range [m]*/ int ii; ht = meta_get_sat_height(meta, 0, 0); re = meta_get_earth_radius(meta, 0, 0); sr = meta_get_slant(meta,0,0); /* calculate ground range to first point */ rg0 = re * acos((ht*ht+re*re-sr*sr) / (2*ht*re)); /* begin loop */ rg = rg0; for (ii = 0; ii<MAX_IMG_SIZE; ii++) { double this_slant = sqrt(ht*ht+re*re-2.0*ht*re*cos(rg/re)); sr2gr[ii] = (this_slant - sr) / srinc; rg += newSize; } }
static double rangeTime(meta_parameters *meta, int sample) { return (meta_get_slant(meta, 0.0, (double) sample) / SPD_LIGHT); }
baseline find_baseline(char *file1,char *file2) { #define MAX_STVEC 1000 int N_STVEC;/*Number of state vectors in scene-- must be >=2.*/ int i; double range,dop; double Bn[MAX_STVEC],Bp[MAX_STVEC]; stateVector stVec; baseline base = {0.0, 0.0, 0.0, 0.0, 1.0}; meta_parameters *meta1 = meta_read(file1); meta_parameters *meta2 = meta_read(file2); int ncol; quietflag = TRUE; ncol = meta1->sar->original_sample_count; /*Calculate the range and doppler of beam center.*/ range = meta_get_slant(meta1,0,ncol/2); dop = meta_get_dop(meta1,0,ncol/2); if (meta1->state_vectors==NULL) { sprintf(errbuf," ERROR: The image file '%s' has no\n" " state vectors!\n",file1); printErr(errbuf); } N_STVEC=meta1->state_vectors->vector_count; /*Get image 1's state vectors, and advance each of image 2's so they line up. This creates an array of normal and parallel baseline values.*/ for (i=0;i<N_STVEC;i++) { stVec=meta1->state_vectors->vecs[i].vec; get_sep(stVec,meta2,range,dop,&Bn[i],&Bp[i]); } /*Find constant baseline value: Just average the normal and parallel baselines. */ for (i=0;i<N_STVEC;i++) { base.Bn+=Bn[i]; base.Bp+=Bp[i]; } base.Bn/=N_STVEC; base.Bp/=N_STVEC; i=N_STVEC/2; if (!quietflag) printf(" Orbit Curvature=%.2fm normal, %.2fm parallel\n", Bn[i]-base.Bn,Bp[i]-base.Bp); /*Find change in baseline value: Average the baseline delta for each point. */ for (i=0;i<N_STVEC;i++) { /* double weight=0.5-((double)i)/(N_STVEC-1);*/ /* change we made once for Radarsat processing; needs to be looked at some more when time permits */ double weight=-0.5+((double)i)/(N_STVEC-1); if (weight!=0.0) { base.dBn+=(Bn[i]-base.Bn)/weight; base.dBp+=(Bp[i]-base.Bp)/weight; } } base.dBn/=(N_STVEC-1); base.dBp/=(N_STVEC-1); base.temporal=get_days(meta1->state_vectors,meta2->state_vectors); return base; }
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); }
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); }
int main (int argc, char *argv []) { FILE *fp; getRec *signalGetRec; file *f; int ii, kk, ll, mm, give_usage_action=0, offset; int filter_azimuth, filter_range, filter_size; struct ARDOP_PARAMS params; meta_parameters *meta; complexFloat *image_in, *image_out, impulse_response, sum; double lines=0.0, samples=0.0; double time, range_time, azimuth_time, beam_center_time, pulse_duration; double pulse_envelope, antenna_beam_pattern, wavelength, chirp_slope; double slant_range, pulse_repetition_frequency, range_sampling_rate; double exposure_time, r, theta; printf("%s\n",date_time_stamp()); fflush(NULL); printf("Program: atdp\n\n"); logflag=0; quietflag=1; give_usage_action=parse_cla(argc,argv,¶ms,&meta); if (give_usage_action==0) give_usage(argv[0]); if (logflag) { StartWatchLog(fLog); printLog("Program: atdp\n\n"); } printf(" Initialization ...\n"); /* Read input out of SAR processing parameter file */ atdp_setup(¶ms,meta,&f,&signalGetRec); /* Define some parameters */ beam_center_time = samples * lines / 2; // check!!! pulse_duration = params.pulsedur; wavelength = params.wavl; chirp_slope = params.slope; pulse_repetition_frequency = params.prf; range_sampling_rate = params.fs; exposure_time = 0.64; // fix me filter_azimuth = (int)(exposure_time * pulse_repetition_frequency / 2 + 0.5); filter_range = (int)(pulse_duration * range_sampling_rate / 2 + 0.5); filter_size = filter_azimuth * filter_range * 4; /* Write metadata */ lines = signalGetRec->nLines; samples = signalGetRec->nSamples; meta->general->line_count = lines - filter_azimuth*2; meta->general->sample_count = samples - filter_range*2; meta->general->data_type = COMPLEX_REAL32; meta->general->image_data_type = COMPLEX_IMAGE; meta_write(meta, f->out_cpx); /* Arrange for memory */ image_in = (complexFloat *) MALLOC (sizeof(complexFloat)*samples*lines); image_out = (complexFloat *) MALLOC (sizeof(complexFloat)*meta->general->sample_count); /* Read raw SAR image */ for (ii=0; ii<lines; ii++) getSignalLine(signalGetRec,ii,&image_in[ii],0,samples); /* Open output image */ fp = FOPEN(f->out_cpx, "wb"); /* Loop through the image */ printf(" Start SAR processing raw image ...\n"); printf(" Match filter size: %i lines, %i samples\n", filter_azimuth*2, filter_range*2); for (ii=filter_azimuth; ii<lines-filter_azimuth; ii++) { for (kk=filter_range; kk<samples-filter_range; kk++) { offset = ii*samples + kk; ll=0;mm=0; /* Apply match filter */ for (ll=0; ll<filter_azimuth*2; ll++) { for (mm=0; mm<filter_range*2; mm++) { sum.real = 0.0; sum.imag = 0.0; /* Determine range and azimuth time */ range_time = (kk+mm) * meta->sar->range_time_per_pixel; azimuth_time = (ii+ll) * meta->sar->azimuth_time_per_pixel; /* Envelope of transmitted radar pulse */ slant_range = meta_get_slant(meta, ii+ll, kk+mm); time = range_time - 2*slant_range/speedOfLight; pulse_envelope = rect(time, pulse_duration); /* Antenn beam pattern */ time = azimuth_time - beam_center_time; antenna_beam_pattern = rect(time, pulse_duration); /* Impulse response function - Straight out of Ian Cumming's book (4-42), written in polar coordinates. For complex data, we have z = r * exp(i*theta). The real part out of that is r*cos(theta), the imaginary part is r*sin(theta).*/ r = pulse_envelope * antenna_beam_pattern; theta = (-4*PI * slant_range * wavelength) + (PI * chirp_slope * SQR(range_time - 2*slant_range / speedOfLight)); /* Real and imaginary part of impulse response function */ impulse_response.real = r * cos(theta); impulse_response.imag = r * sin(theta); /* Multiplication of raw image with time reversed complex conjugate impulse response function */ sum.real += image_in[offset + ll*filter_range*2 + mm].real * impulse_response.real + image_in[offset + ll*filter_range*2 + mm].imag * impulse_response.imag; sum.imag += image_in[offset + ll*filter_range*2 + mm].imag * impulse_response.real - image_in[offset + ll*filter_range*2 + mm].real * impulse_response.imag; } } image_out[kk].real = sum.real / filter_size; image_out[kk].imag = sum.imag / filter_size; //printf(" image: line = %5i, sample = %5i\r", ii, kk); } put_complexFloat_line(fp, meta, ii, image_out); if (ii%200 == 0) printf(" Processed line %5d\n", ii); } FCLOSE(fp); return(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; }