/* Calculate minimum, maximum, mean and standard deviation for a floating point image. A mask value can be defined that is excluded from this calculation. If no mask value is supposed to be used, pass the mask value as NAN. */ void calc_stats(float *data, long long pixel_count, double mask, double *min, double *max, double *mean, double *stdDev) { long long ii, pix; /* Initialize values */ *min = 99999; *max = -99999; *mean = 0.0; *stdDev = 0.0; pix = 0; asfPrintStatus("\nFinding min, max, and mean...\n"); for (ii=0; ii<pixel_count; ii++) { asfPercentMeter(((double)ii/(double)pixel_count)); if (!ISNAN(mask)) { if (data[ii] < *min && !FLOAT_EQUIVALENT(data[ii], mask)) *min = data[ii]; if (data[ii] > *max && !FLOAT_EQUIVALENT(data[ii], mask)) *max = data[ii]; if (!FLOAT_EQUIVALENT(data[ii], mask)) { *mean += data[ii]; pix++; } } else { if (data[ii] < *min) *min = data[ii]; if (data[ii] > *max) *max = data[ii]; *mean += data[ii]; ++pix; } } asfPercentMeter(1.0); *mean /= pix; asfPrintStatus("\nCalculating standard deviation...\n"); for (ii=0; ii<pixel_count; ii++) { asfPercentMeter(((double)ii/(double)pixel_count)); if (!ISNAN(mask)) { if (!FLOAT_EQUIVALENT(data[ii], mask)) *stdDev += (data[ii] - *mean) * (data[ii] - *mean); } else *stdDev += (data[ii] - *mean) * (data[ii] - *mean); } *stdDev = sqrt(*stdDev/(pix - 1)); asfPercentMeter(1.0); return; }
bool calc_pslr(float *profile, int size, int peak, int sidelobe_min, int sidelobe_max, float *pslr) { int larger_lobe; float amplitude, peak_power, side_power; // Select the larger of the two sidelobes larger_lobe = sidelobe_max; if (profile[sidelobe_min] > profile[sidelobe_max]) larger_lobe = sidelobe_min; // Calculate peak power plus amplitude and power of the larger sidelobe amplitude = profile[larger_lobe]; peak_power = profile[peak]*profile[peak]; side_power = amplitude*amplitude; // Calculate PSLR if (!FLOAT_EQUIVALENT(side_power, 0.0)) { *pslr = 10*log(side_power/peak_power); return TRUE; } else { *pslr = -1.0; return FALSE; } }
/* Estimate mean and standard deviation of an image by taking regular sampling points and doing the math with those. A mask value can be defined that is excluded from this calculation. If no mask value is supposed to be used, pass the mask value as NAN. */ void estimate_stats(FILE *fpIn, meta_parameters *meta, int lines, int samples, double mask, double *min, double *max, double *mean, double *stdDev) { float *imgLine = (float *) MALLOC(sizeof(float) * samples); double *stats, sum=0.0, variance=0.0; int ii, kk, line_increment, sample_increment; long pix=0, valid=0; #define grid 100 /* Define the necessary parameters */ stats = (double *) MALLOC(sizeof(double) * grid * grid); line_increment = lines / grid; sample_increment = samples / grid; /* Collect values from sample grid */ for (ii=0; ii<lines; ii+=line_increment) { get_float_line(fpIn, meta, ii, imgLine); for (kk=0; kk<samples; kk+=sample_increment) { if (!ISNAN(mask)) { if (FLOAT_EQUIVALENT(imgLine[kk], mask)) stats[pix] = NAN; else { stats[pix] = imgLine[kk]; valid++; } } else { stats[pix] = imgLine[kk]; valid++; } pix++; } } FSEEK64(fpIn, 0, 0); /* Estimate min, max, mean and standard deviation */ *min = 99999; *max = -99999; for (ii=0; ii<grid*grid; ii++) if (!ISNAN(stats[ii])) { if (stats[ii] < *min) *min = stats[ii]; if (stats[ii] > *max) *max = stats[ii]; sum += stats[ii]; } *mean = sum / valid; for (ii=0; ii<grid*grid; ii++) if (!ISNAN(stats[ii])) variance += (stats[ii]-*mean) * (stats[ii]-*mean); *stdDev = sqrt(variance / (valid-1)); return; }
int asf_logscale(const char *inFile, const char *outFile) { int ii, jj, kk; meta_parameters *meta = meta_read(inFile); int band_count = meta->general->band_count; int sample_count = meta->general->sample_count; int line_count = meta->general->line_count; float *bufIn = (float *) MALLOC(sizeof(float)*sample_count); float *bufOut = (float *) MALLOC(sizeof(float)*sample_count); char *input = appendExt(inFile, ".img"); char *output = appendExt(outFile, ".img"); FILE *fpIn = FOPEN(input, "rb"); FILE *fpOut = FOPEN(output, "wb"); for (kk=0; kk<band_count; kk++) { for (ii=0; ii<line_count; ii++) { get_band_float_line(fpIn, meta, kk, ii, bufIn); for (jj=0; jj<sample_count; jj++) { if (FLOAT_EQUIVALENT(bufIn[jj], 0.0)) bufOut[jj] = 0.0; else bufOut[jj] = 10.0 * log10(bufIn[jj]); } put_band_float_line(fpOut, meta, kk, ii, bufOut); asfLineMeter(ii, line_count); } } meta_write(meta, outFile); meta_free(meta); FCLOSE(fpIn); FCLOSE(fpOut); FREE(bufIn); FREE(bufOut); FREE(input); FREE(output); return FALSE; }
static void interpolate_prc_vectors(doris_prc_polar *stVec, double time, int start, int stop, doris_prc_cartesian *outVec) { int t1 = stVec[start].time; int tn = stVec[stop].time; double trel = (double)(time-t1)/(double)(tn-t1)*8.0 + 1.0; int itrel = MAX(0, MIN((int)(trel + 0.5) - 4, 0)); double x = trel - itrel; double teller = (x-1)*(x-2)*(x-3)*(x-4)*(x-5)*(x-6)*(x-7)*(x-8)*(x-9); int kx; if (FLOAT_EQUIVALENT(teller, 0.0)) { kx = start + (int)(x + 0.5) - 1; doris_prc_polar polarVec; geocentric_latlon(stVec[kx], &polarVec); polar2cartesian(polarVec, &outVec); } else { doris_prc_cartesian cartVec; outVec->time = 0.0; outVec->x = 0.0; outVec->y = 0.0; outVec->z = 0.0; int noemer[9] = {40320, -5040, 1440, -720, 576, -720, 1440, -5040, 40320}; for (kx=0; kx<9; kx++) { doris_prc_polar polarVec; geocentric_latlon(stVec[start+kx], &polarVec); polar2cartesian(polarVec, &cartVec); double coeff = teller/noemer[kx]/(x-kx-1); outVec->time = outVec->time + coeff*cartVec.time; outVec->x = outVec->x + coeff*cartVec.x; outVec->y = outVec->y + coeff*cartVec.y; outVec->z = outVec->z + coeff*cartVec.z; } } }
// Code ported from Delft getorb Fortran code // http://www.deos.tudelft.nl/ers/precorbs/tools/getorb_pack.shtml static stateVector interpolate_prc_vector_position(meta_state_vectors *stVec, double time) { stateVector outVec; if (stVec->vector_count != 9) asfPrintError("This function needs nine state vectors.\n" "It should not have been called with this metadata.\n"); double t1 = stVec->vecs[0].time; double tn = stVec->vecs[8].time; double trel = (time-t1)/(tn-t1)*8.0 + 1.0; int itrel = MAX(0, MIN((int)(trel + 0.5) - 4, 0)); double x = trel - itrel; double teller = (x-1)*(x-2)*(x-3)*(x-4)*(x-5)*(x-6)*(x-7)*(x-8)*(x-9); int kx; if (FLOAT_EQUIVALENT(teller, 0.0)) { kx = (int)(x + 0.5) - 1; outVec.pos.x = stVec->vecs[kx].vec.pos.x; outVec.pos.y = stVec->vecs[kx].vec.pos.y; outVec.pos.z = stVec->vecs[kx].vec.pos.z; } else { outVec.pos.x = 0.0; outVec.pos.y = 0.0; outVec.pos.z = 0.0; int noemer[9] = {40320, -5040, 1440, -720, 576, -720, 1440, -5040, 40320}; for (kx=0; kx<9; kx++) { double coeff = teller/noemer[kx]/(x-kx-1); outVec.pos.x = outVec.pos.x + coeff*stVec->vecs[kx].vec.pos.x; outVec.pos.y = outVec.pos.y + coeff*stVec->vecs[kx].vec.pos.y; outVec.pos.z = outVec.pos.z + coeff*stVec->vecs[kx].vec.pos.z; } } return outVec; }
void calc_stats_rmse_from_file(const char *inFile, char *band, double mask, double *min, double *max, double *mean, double *stdDev, double *rmse, gsl_histogram **histogram) { double se; int ii,jj; *min = 999999; *max = -999999; *mean = 0.0; meta_parameters *meta = meta_read(inFile); int band_number = (!band || strlen(band) == 0 || strcmp(band, "???") == 0) ? 0 : get_band_number(meta->general->bands, meta->general->band_count, band); long offset = meta->general->line_count * band_number; float *data = MALLOC(sizeof(float) * meta->general->sample_count); // pass 1 -- calculate mean, min & max FILE *fp = FOPEN(inFile, "rb"); long long pixel_count=0; asfPrintStatus("\nCalculating min, max, and mean...\n"); for (ii=0; ii<meta->general->line_count; ++ii) { asfPercentMeter(((double)ii/(double)meta->general->line_count)); get_float_line(fp, meta, ii + offset, data); for (jj=0; jj<meta->general->sample_count; ++jj) { if (ISNAN(mask) || !FLOAT_EQUIVALENT(data[jj], mask)) { if (data[jj] < *min) *min = data[jj]; if (data[jj] > *max) *max = data[jj]; *mean += data[jj]; ++pixel_count; } } } asfPercentMeter(1.0); FCLOSE(fp); *mean /= pixel_count; // Guard against weird data if(!(*min<*max)) *max = *min + 1; // Initialize the histogram. const int num_bins = 256; gsl_histogram *hist = gsl_histogram_alloc (num_bins); gsl_histogram_set_ranges_uniform (hist, *min, *max); *stdDev = 0.0; // pass 2 -- update histogram, calculate standard deviation fp = FOPEN(inFile, "rb"); asfPrintStatus("\nCalculating standard deviation, rmse, and histogram...\n"); se = 0.0; for (ii=0; ii<meta->general->line_count; ++ii) { asfPercentMeter(((double)ii/(double)meta->general->line_count)); get_float_line(fp, meta, ii + offset, data); for (jj=0; jj<meta->general->sample_count; ++jj) { if (ISNAN(mask) || !FLOAT_EQUIVALENT(data[jj], mask)) { *stdDev += (data[jj] - *mean) * (data[jj] - *mean); gsl_histogram_increment (hist, data[jj]); se += (data[jj] - *mean) * (data[jj] - *mean); } } } asfPercentMeter(1.0); FCLOSE(fp); *stdDev = sqrt(*stdDev/(pixel_count - 1)); *rmse = sqrt(se/(pixel_count - 1)); FREE(data); *histogram = hist; }
unsigned char *floats_to_bytes_ext(float *data, long long pixel_count, float mask, scale_t scaling, float scale_factor) { long long ii; double imin=99999, imax=-99999, imean=0, isdev=0; double diff_min, diff_max, omin, omax, slope, offset; unsigned char *pixels = malloc (pixel_count * sizeof (unsigned char)); switch (scaling) { case TRUNCATE: /* Compute all the output pixels truncating the input values */ for (ii=0; ii<pixel_count; ii++) if (data[ii] < 0) { pixels[ii] = 0; } else if (data[ii] > 255) { pixels[ii] = 255; } else pixels[ii] = data[ii] + 0.5; break; case MINMAX: /* Determine the minimum and maximum values for the image. Exclude the mask value for this calculation */ for (ii=0; ii<pixel_count; ii++) { if (!ISNAN(mask)) { if (data[ii] < imin && !FLOAT_EQUIVALENT(data[ii], mask)) imin = data[ii]; if (data[ii] > imax && !FLOAT_EQUIVALENT(data[ii], mask)) imax = data[ii]; } else { if (data[ii] < imin) imin = data[ii]; if (data[ii] > imax) imax = data[ii]; } } omin = imin; omax = imax; /* Compute all the output pixels stretching the minimum and maximum value into the byte range */ slope = 255 / (omax-omin); offset = -slope * omin; for (ii=0; ii<pixel_count; ii++) { if ((slope * data[ii] + offset) < 0) pixels[ii] = 0; else if ((slope * data[ii] + offset) > 255) pixels[ii] = 255; else pixels[ii] = slope * data[ii] + offset; } break; case SIGMA: /* Determine the minimum, maximum, mean, and standard deviation for the image. Exclude the mask value from the calculation */ calc_stats(data, pixel_count, 0.0, &imin, &imax, &imean, &isdev); /* Apply 2 sigma to calculate new minimum and maximum */ diff_min = imean - 2*isdev; diff_max = imean + 2*isdev; omin = diff_min; omax = diff_max; if (diff_min < imin) omin = imin; if (diff_max > imax) omax = imax; /* Computing output pixels applying the sigma mapping */ slope = 255 / (omax-omin); offset = -slope * omin; for (ii=0; ii<pixel_count; ii++) { if ((slope * data[ii] + offset) < 0) pixels[ii] = 0; else if ((slope * data[ii] + offset) > 255) pixels[ii] = 255; else pixels[ii] = slope * data[ii] + offset; } break; case FIXED: for (ii=0; ii<pixel_count; ii++) pixels[ii] = data[ii]*scale_factor; break; default: asfPrintError("Undefined scaling mechanism!"); break; } return pixels; }
/* Create histogram of the data and get the summation of the * square of (sample-mean) to use in calculation of rmse & stdev */ stat_parameters calc_hist(stat_parameters stats, char *sar_name, int band, meta_parameters *meta, double sum_of_samples, long samples_counted, int mask_flag) { FILE *fp; long start_line, start_sample, window_height, window_width; long percent_complete, line, sample, ii, band_offset; double diff_squared_sum=0.0; float *data_line; start_line = stats.upper_left_line; start_sample = stats.upper_left_samp; window_height = stats.lower_right_line - start_line; window_width = stats.lower_right_samp - start_sample; data_line = (float *)MALLOC(sizeof(float)*meta->general->sample_count); fp = FOPEN(sar_name, "r"); /* Initialize the histogram array */ for (ii=0; ii<256; ii++) stats.histogram[ii] = 0; if (meta->general->data_type != ASF_BYTE) { /* Set slope and offset, to map pixels to [0..255]. * byte = slope * in + offset * 0 = slope * min + offset * 255 = slope * max + offset * Therefore: */ stats.slope = 255.0 / (stats.max-stats.min); stats.offset = -stats.slope * stats.min; } /* Get histogram of the data. If its byte data just slap it into the * histogram; otherwise use slope & offset to scale the data */ stats.mean = sum_of_samples / (double)samples_counted; percent_complete=0; band_offset = band * meta->general->line_count; for (line=start_line+band_offset; line<start_line+window_height+band_offset; line++) { if (!quietflag) asfPercentMeter((float)(line-start_line-band_offset)/(float)(window_height-start_line)); get_float_line(fp, meta, line, data_line); for (sample=start_sample; sample<start_sample+window_width; sample++) { int bin = (meta->general->data_type == ASF_BYTE) ? (int)data_line[sample] : (int)(stats.slope*data_line[sample]+stats.offset); if (bin < 0) bin = 0; else if (bin > 255) bin = 255; if ( mask_flag && FLOAT_EQUIVALENT(data_line[sample],stats.mask) ) continue; stats.histogram[bin]++; diff_squared_sum += SQR(data_line[sample] - stats.mean); } } if (!quietflag) asfPercentMeter(1.0); FREE(data_line); FCLOSE(fp); /* Populate stats structure */ stats.rmse = sqrt( fabs( diff_squared_sum / (double)samples_counted ) ); stats.std_deviation = sqrt( fabs( diff_squared_sum / (double)(samples_counted-1) ) ); return stats; }
int main(int argc, char **argv) { double min, max; /* Minimum & maximum sample values */ double sum_of_samples=0.0; /* Sum of all samples accounted for */ double sum_of_squared_samples=0.0; /* Sum of all squared samples accounted for*/ double trim_fraction; /* Fraction used to trim the histogram */ int ii; /* Loop index */ long samples_counted=0; /* Number of all samples accounted for */ float *data_line; /* Buffer for a line of samples */ long line, sample; /* Line and sample indices */ long num_lines, num_samples; /* Number of lines and samples */ int percent_complete=0; /* Percent of data sweep completed */ int overmeta_flag=FALSE; /* If TRUE write over current .meta file */ int overstat_flag=FALSE; /* If TRUE write over current .stat file */ int nometa_flag=FALSE; /* If TRUE do not write .meta file */ int nostat_flag=FALSE; /* If TRUE do not write .stat file */ int mask_flag=FALSE; /* TRUE if user specifies a mask value */ int trim_flag=FALSE; /* If TRUE trim histogram */ double mask=NAN; /* Value to ignore while caculating stats*/ char meta_name[261]; /* Meta file name */ meta_parameters *meta; /* SAR meta data structure */ char sar_name[256]; /* SAR file name WITH extention */ FILE *sar_file; /* SAR data file pointer to take stats on*/ stat_parameters *stats; /* Statistics structure */ char stat_name[261]; /* Stats file name */ extern int currArg; /* Pre-initialized to 1 */ /* We initialize these to a magic number for checking. */ long start_line = -1; /* Window starting line. */ long start_sample = -1; /* Window starting sample. */ long window_height = -1; /* Window height in lines. */ long window_width = -1; /* Window width in samples. */ /* parse command line */ handle_license_and_version_args(argc, argv, "stats"); logflag=quietflag=FALSE; while (currArg < (argc-1)) { char *key = argv[currArg++]; if (strmatch(key,"-quiet")) { quietflag=TRUE; } else 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); mask = atof(GET_ARG(1)); mask_flag=TRUE; } else if (strmatch(key,"-overmeta")) { overmeta_flag=TRUE; } else if (strmatch(key,"-overstat")) { overstat_flag=TRUE; } else if (strmatch(key,"-nometa")) { nometa_flag=TRUE; } else if (strmatch(key,"-nostat")) { nostat_flag=TRUE; } else if (strmatch(key,"-startline")) { CHECK_ARG(1); nometa_flag=TRUE; /* Implied. */ start_line = atol(GET_ARG(1)); if ( start_line < 0 ) { printf("error: -startline argument must be greater than or equal to zero\n"); usage(argv[0]); } } else if (strmatch(key,"-startsample")) { CHECK_ARG(1); nometa_flag=TRUE; /* Implied. */ start_sample = atol(GET_ARG(1)); if ( start_sample < 0 ) { printf("error: -startsample argument must be greater than or equal to zero\n"); usage(argv[0]); } } else if (strmatch(key,"-width")) { CHECK_ARG(1); nometa_flag=TRUE; /* Implied. */ window_width = atol(GET_ARG(1)); if ( window_width < 0 ) { printf("error: -width argument must be greater than or equal to zero\n"); usage(argv[0]); } } else if (strmatch(key,"-height")) { CHECK_ARG(1); nometa_flag=TRUE; /* Implied. */ window_height = atol(GET_ARG(1)); if ( window_height < 0 ) { printf("error: -height argument must be greater than or equal to zero\n"); usage(argv[0]); } } else if (strmatch(key,"-trim")) { CHECK_ARG(1); trim_flag=TRUE; /* Implied. */ trim_fraction = atof(GET_ARG(1)); } else {printf( "\n**Invalid option: %s\n",argv[currArg-1]); usage(argv[0]);} } if ((argc-currArg)<1) {printf("Insufficient arguments.\n"); usage(argv[0]);} strcpy (sar_name, argv[currArg]); char *ext = findExt(sar_name); if (ext == NULL || strcmp("IMG", uc(ext)) != 0) { strcpy(sar_name, appendExt(sar_name, ".img")); } create_name(meta_name, sar_name, ".meta"); create_name(stat_name, sar_name, ".stat"); printf("\nProgram: stats\n\n"); if (logflag) { fprintf(fLog, "\nProgram: stats\n\n"); } printf("\nCalculating statistics for %s\n\n", sar_name); if (logflag) { fprintf(fLog,"\nCalculating statistics for %s\n\n", sar_name); } meta = meta_read(meta_name); num_lines = meta->general->line_count; num_samples = meta->general->sample_count; if ( start_line == -1 ) start_line = 0; if ( start_line > num_lines ) { printf("error: -startline argument is larger than index of last line in image\n"); exit(EXIT_FAILURE); } if ( start_sample == -1 ) start_sample = 0; if ( start_sample > num_samples ) { printf("error: -startsample argument is larger than index of last sample in image\n"); exit(EXIT_FAILURE); } if ( window_height == -1 ) window_height = num_lines; if ( start_line + window_height > num_lines ) { printf("warning: window specified with -startline, -height options doesn't fit in image\n"); } if ( window_width == -1 ) window_width = num_samples; if ( start_sample + window_width > num_samples ) { printf("warning: window specified with -startsample, -width options doesn't fit in image\n"); } /* Make sure we don't over write any files that we don't want to */ if (meta->stats && !overmeta_flag && !nometa_flag) { printf(" ** The meta file already has a populated statistics structure.\n" " ** If you want to run this program and replace that structure,\n" " ** then use the -overmeta option to do so. If you want to run\n" " ** this program, but don't want to replace the structure, use\n" " ** the -nometa option.\n"); if (logflag) { fprintf(fLog, " ** The meta file already has a populated statistics structure.\n" " ** If you want to run this program and replace that structure,\n" " ** then use the -overmeta option to do so. If you want to run\n" " ** this program, but don't want to replace the structure, use\n" " ** the -nometa option.\n"); } exit(EXIT_FAILURE); } if (fileExists(stat_name) && !overstat_flag && !nostat_flag) { printf(" ** The file, %s, already exists. If you want to\n" " ** overwrite it, then use the -overstat option to do so.\n" " ** If you want to run the progam but don't want to write\n" " ** over the current file, then use the -nostat option.\n", stat_name); if (logflag) { fprintf(fLog, " ** The file, %s, already exists. If you want to\n" " ** overwrite it, then use the -overstat option to do so.\n" " ** If you want to run the progam but don't want to write\n" " ** over the current file, then use the -nostat option.\n", stat_name); } exit(EXIT_FAILURE); } /* Let user know the window in which the stats will be taken */ if ((start_line!=0) || (start_sample!=0) || (window_height!=num_lines) || (window_width!=num_samples)) { if (!quietflag) { printf("Taking statistics on a window with upper left corner (%ld,%ld)\n" " and lower right corner (%ld,%ld)\n", start_sample, start_line, window_width+start_sample, window_height+start_line); } if (logflag && !quietflag) { fprintf(fLog, "Taking statistics on a window with upper left corner (%ld,%ld)\n" " and lower right corner (%ld,%ld)\n", start_sample, start_line, window_width+start_sample, window_height+start_line); } } /* Allocate line buffer */ data_line = (float *)MALLOC(sizeof(float)*num_samples); if (meta->stats) FREE(meta->stats); if (meta->general->band_count <= 0) { printf(" ** Band count in the existing data is missing or less than zero.\nDefaulting to one band.\n"); if (logflag) { fprintf(fLog, " ** Band count in the existing data is missing or less than zero.\nDefaulting to one band.\n"); } meta->general->band_count = 1; } meta->stats = meta_statistics_init(meta->general->band_count); if (!meta->stats) { printf(" ** Cannot allocate memory for statistics data structures.\n"); if (logflag) { fprintf(fLog, " ** Cannot allocate memory for statistics data structures.\n"); } exit(EXIT_FAILURE); } stats = (stat_parameters *)MALLOC(sizeof(stat_parameters) * meta->stats->band_count); if (!stats) { printf(" ** Cannot allocate memory for statistics data structures.\n"); if (logflag) { fprintf(fLog, " ** Cannot allocate memory for statistics data structures.\n"); } exit(EXIT_FAILURE); } int band; long band_offset; for (band = 0; band < meta->stats->band_count; band++) { /* Find min, max, and mean values */ if (!quietflag) printf("\n"); if (logflag && !quietflag) fprintf(fLog,"\n"); min = 100000000; max = -100000000; sum_of_samples=0.0; sum_of_squared_samples=0.0; percent_complete=0; band_offset = band * meta->general->line_count; sar_file = FOPEN(sar_name, "r"); for (line=start_line+band_offset; line<start_line+window_height+band_offset; line++) { if (!quietflag) asfPercentMeter((float)(line-start_line-band_offset)/(float)(window_height-start_line)); get_float_line(sar_file, meta, line, data_line); for (sample=start_sample; sample<start_sample+window_width; sample++) { if ( mask_flag && FLOAT_EQUIVALENT(data_line[sample],mask) ) continue; if (data_line[sample] < min) min=data_line[sample]; if (data_line[sample] > max) max=data_line[sample]; sum_of_samples += data_line[sample]; sum_of_squared_samples += SQR(data_line[sample]); samples_counted++; } } if (!quietflag) asfPercentMeter(1.0); // if (!quietflag) printf("\rFirst data sweep: 100%% complete.\n"); FCLOSE(sar_file); stats[band].min = min; stats[band].max = max; stats[band].upper_left_line = start_line; stats[band].upper_left_samp = start_sample; stats[band].lower_right_line = start_line + window_height; stats[band].lower_right_samp = start_sample + window_width; stats[band].mask = mask; stats[band] = calc_hist(stats[band], sar_name, band, meta, sum_of_samples, samples_counted, mask_flag); /* Remove outliers and trim the histogram by resetting the minimum and and maximum */ if (trim_flag) { register int sum=0, num_pixels, minDex=0, maxDex=255; double overshoot, width; num_pixels = (int)(samples_counted*trim_fraction); minDex = 0; while (sum < num_pixels) sum += stats[band].histogram[minDex++]; if (minDex-1>=0) overshoot = (double)(num_pixels-sum)/stats[band].histogram[minDex-1]; else overshoot = 0; stats[band].min = (minDex-overshoot-stats[band].offset)/stats[band].slope; sum=0; while (sum < num_pixels) sum += stats[band].histogram[maxDex--]; if (maxDex+1<256) overshoot = (double)(num_pixels-sum)/stats[band].histogram[maxDex+1]; else overshoot = 0; stats[band].max = (maxDex+1+overshoot-stats[band].offset)/stats[band].slope; /* Widening the range for better visual effect */ width = (stats[band].max-stats[band].min)*(1/(1.0-2*trim_fraction)-1); stats[band].min -= width/2; stats[band].max += width/2; /* Couple useful corrections borrowed from SARview */ if ((stats[band].max-stats[band].min) < 0.01*(max-min)) { stats[band].max = max; stats[band].min = min; } if (min == 0.0) stats[band].min=0.0; if (stats[band].min == stats[band].max) stats[band].max = stats[band].min + MICRON; stats[band].slope = 255.0/(stats[band].max-stats[band].min); stats[band].offset = -stats[band].slope*stats[band].min; stats[band] = calc_hist(stats[band], sar_name, band, meta, sum_of_samples, samples_counted, mask_flag); } } if(data_line)FREE(data_line); /* Populate meta->stats structure */ char **band_names = NULL; if (meta_is_valid_string(meta->general->bands) && strlen(meta->general->bands) && meta->general->band_count > 0) { band_names = extract_band_names(meta->general->bands, meta->general->band_count); } else { if (meta->general->band_count <= 0) meta->general->band_count = 1; band_names = (char **) MALLOC (meta->general->band_count * sizeof(char *)); int i; for (i=0; i<meta->general->band_count; i++) { band_names[i] = (char *) MALLOC (64 * sizeof(char)); sprintf(band_names[i], "%02d", i); } } int band_no; for (band_no = 0; band_no < meta->stats->band_count; band_no++) { strcpy(meta->stats->band_stats[band_no].band_id, band_names[band_no]); meta->stats->band_stats[band_no].min = stats[band_no].min; meta->stats->band_stats[band_no].max = stats[band_no].max; meta->stats->band_stats[band_no].mean = stats[band_no].mean; meta->stats->band_stats[band_no].rmse = stats[band_no].rmse; meta->stats->band_stats[band_no].std_deviation = stats[band_no].std_deviation; meta->stats->band_stats[band_no].mask = stats[band_no].mask; } if (band_names) { int i; for (i=0; i<meta->general->band_count; i++) { if (band_names[i]) FREE (band_names[i]); } FREE(band_names); } /* Print findings to the screen (and log file if applicable)*/ if (!quietflag) { printf("\n"); printf("Statistics found:\n"); if (mask_flag) { printf("Used mask %-16.11g\n",mask); } printf("Number of bands: %d\n", meta->stats->band_count); for (band=0; band<meta->stats->band_count; band++) { printf("\n\nBand name = \"%s\"\n", meta->stats->band_stats[band].band_id); printf("Minimum = %-16.11g\n",stats[band].min); printf("Maximum = %-16.11g\n",stats[band].max); printf("Mean = %-16.11g\n",stats[band].mean); printf("Root mean squared error = %-16.11g\n", stats[band].rmse); printf("Standard deviation = %-16.11g\n", stats[band].std_deviation); printf("\n"); printf("Data fit to [0..255] using equation: byte = %g * sample + %g\n", stats[band].slope, stats[band].offset); if (trim_flag) printf("Trimming fraction = %.3g\n", trim_fraction); printf("\n"); printf("Histogram:\n"); for (ii=0; ii<256; ii++) { if (ii%8 == 0) { printf("%s%3i-%3i:", (ii==0) ? "" : "\n", ii, ii+7); } printf(" %8i", stats[band].histogram[ii]); } printf("\n"); } } if (logflag && !quietflag) { fprintf(fLog,"Statistics found:\n"); if (mask_flag) { fprintf(fLog,"Used mask %-16.11g\n",mask); } fprintf(fLog,"Number of bands: %d\n", meta->stats->band_count); for (band=0; band<meta->stats->band_count; band++) { fprintf(fLog,"\n\nBand name = \"%s\"\n", meta->stats->band_stats[band].band_id); fprintf(fLog,"Minimum = %-16.11g\n",stats[band].min); fprintf(fLog,"Maximum = %-16.11g\n",stats[band].max); fprintf(fLog,"Mean = %-16.11g\n",stats[band].mean); fprintf(fLog,"Root mean squared error = %-16.11g\n", stats[band].rmse); fprintf(fLog,"Standard deviation = %-16.11g\n", stats[band].std_deviation); fprintf(fLog,"\n"); fprintf(fLog,"Data fit to [0..255] using equation: byte = %g * sample + %g\n", stats[band].slope, stats[band].offset); if (trim_flag) fprintf(fLog,"Trimming fraction = %.3g\n", trim_fraction); fprintf(fLog,"\n"); fprintf(fLog,"Histogram:\n"); for (ii=0; ii<256; ii++) { if (ii%8 == 0) { fprintf(fLog,"%s%3i-%3i:", (ii==0) ? "" : "\n", ii, ii+7); } fprintf(fLog," %8i", stats[band].histogram[ii]); } fprintf(fLog,"\n"); } } /* Write out .meta and .stat files */ if (!nometa_flag) meta_write(meta, meta_name); if (!nostat_flag) stat_write(stats, stat_name, meta->stats->band_count); /* Free the metadata structure */ meta_free(meta); /* Report */ if (!quietflag) { printf("\n"); printf("Statistics taken on image file %s.\n",sar_name); if (!nometa_flag) printf("Statistics written to the stats block in %s.\n", meta_name); if (!nostat_flag) printf("Statistics plus histogram written to %s.\n", stat_name); printf("\n"); } if (logflag && !quietflag) { fprintf(fLog,"\n"); fprintf(fLog,"Statistics taken on image file '%s'\n",sar_name); if (!nometa_flag) fprintf(fLog,"Statistics written to the stats block in %s\n", meta_name); if (!nostat_flag) fprintf(fLog,"Statistics plus histogram written to %s\n", stat_name); fprintf(fLog,"\n"); } if (fLog) FCLOSE(fLog); return 0; }
int fftMatch_opt(char *inFile1, char *inFile2, float *offsetX, float *offsetY) { // Generate temporary directory char tmpDir[1024]; char metaFile[1024], outFile[1024], sarFile[1024], opticalFile[1024]; char *baseName = get_basename(inFile1); strcpy(tmpDir, baseName); strcat(tmpDir, "-"); strcat(tmpDir, time_stamp_dir()); create_clean_dir(tmpDir); // Cutting optical to SAR extent asfPrintStatus("Cutting optical to SAR extent ...\n"); sprintf(metaFile, "%s.meta", inFile1); sprintf(outFile, "%s%c%s_sub.img", tmpDir, DIR_SEPARATOR, inFile2); trim_to(inFile2, outFile, metaFile); // Clipping optical image including blackfill asfPrintStatus("\nClipping optical image including blackfill ...\n"); meta_parameters *metaOpt = meta_read(outFile); meta_parameters *metaSAR = meta_read(metaFile); int line_count = metaSAR->general->line_count; int sample_count = metaSAR->general->sample_count; float *floatLine = (float *) MALLOC(sizeof(float)*sample_count); unsigned char *byteLine = (unsigned char *) MALLOC(sizeof(char)*sample_count); FILE *fpOptical = FOPEN(outFile, "rb"); sprintf(sarFile, "%s.img", inFile1); FILE *fpSAR = FOPEN(sarFile, "rb"); sprintf(outFile, "%s%c%s_mask.img", tmpDir, DIR_SEPARATOR, inFile2); sprintf(metaFile, "%s%c%s_mask.meta", tmpDir, DIR_SEPARATOR, inFile2); FILE *fpOut = FOPEN(outFile, "wb"); int ii, kk; for (ii=0; ii<line_count; ii++) { get_float_line(fpSAR, metaSAR, ii, floatLine); get_byte_line(fpOptical, metaOpt, ii, byteLine); for (kk=0; kk<sample_count; kk++) { if (!FLOAT_EQUIVALENT(floatLine[kk], 0.0)) floatLine[kk] = (float) byteLine[kk]; } put_float_line(fpOut, metaSAR, ii, floatLine); } FCLOSE(fpOptical); FCLOSE(fpSAR); FCLOSE(fpOut); meta_write(metaSAR, metaFile); // Edge filtering optical image asfPrintStatus("\nEdge filtering optical image ...\n"); sprintf(opticalFile, "%s%c%s_sobel.img", tmpDir, DIR_SEPARATOR, inFile2); kernel_filter(outFile, opticalFile, SOBEL, 3, 0, 0); // Edge filtering SAR image asfPrintStatus("\nEdge filtering SAR image ...\n"); sprintf(sarFile, "%s%c%s_sobel.img", tmpDir, DIR_SEPARATOR, inFile1); kernel_filter(inFile1, sarFile, SOBEL, 3, 0, 0); // FFT matching on a grid asfPrintStatus("\nFFT matching on a grid ...\n"); float certainty; fftMatch_proj(sarFile, opticalFile, offsetX, offsetY, &certainty); // Clean up remove_dir(tmpDir); return (0); }
int main(int argc, char **argv) { FILE *fpIn, *fpOut, *fpInList, *fpOutList, *fpXml; meta_parameters *meta; extern int currArg; /* from cla.h in asf.h... initialized to 1 */ logflag = 0; // Parse command line args while (currArg < (argc-2)) { char *key=argv[currArg++]; if (strmatch(key,"-log")) { sprintf(logFile, "%s", argv[currArg]); logflag = 1; } else { printf("\n ***Invalid option: %s\n\n", argv[currArg-1]); usage(argv[0]); } } if ((argc-currArg) < 2) { printf("Insufficient arguments.\n"); usage(argv[0]); } asfSplashScreen(argc, argv); char *listInFile = (char *) MALLOC(sizeof(char)*(strlen(argv[1])+1)); strcpy(listInFile, argv[1]); char *outFile = (char *) MALLOC(sizeof(char)*(strlen(argv[2])+1)); strcpy(outFile, argv[2]); // Setup file names char outDirName[512], outFileName[512]; split_dir_and_file(outFile, outDirName, outFileName); char *tmpDir = (char *) MALLOC(sizeof(char)*512); sprintf(tmpDir, "%smeasures-", outDirName); char *tsdir = time_stamp_dir(); strcat(tmpDir, tsdir); FREE(tsdir); create_clean_dir(tmpDir); char *isoStr = iso_date(); // Read header information char inFile[512], imgFile[768], metaFile[768]; char listOutFile[768], citation[50], start[30], end[30], first[30]; char header[120], baseName[512], dirName[512], ext[5]; float x_pix, y_pix, x_map_ll, y_map_ll, x_map_ur, y_map_ur, inc, cat; double lat, lon, height, x, y, z; int ii, kk, nFiles=0, num = 1, sample_count, line_count; image_data_type_t image_data_type; sprintf(listOutFile, "%s%crgps.xml", tmpDir, DIR_SEPARATOR); // Preparing map projection information project_parameters_t pps; projection_type_t proj_type; datum_type_t datum; spheroid_type_t spheroid; read_proj_file("polar_stereographic_north_ssmi.proj", &pps, &proj_type, &datum, &spheroid); pps.ps.false_easting = 0.0; pps.ps.false_northing = 0.0; meta_projection *proj = meta_projection_init(); proj->type = proj_type; proj->datum = HUGHES_DATUM; proj->spheroid = HUGHES_SPHEROID; proj->param = pps; strcpy(proj->units, "meters"); proj->hem = 'N'; spheroid_axes_lengths(spheroid, &proj->re_major, &proj->re_minor); FREE(proj); // Set up supplemental file names: water mask, lat/lon, x/y grids char maskFile[768], latFile[768], lonFile[768], xFile[768], yFile[768]; sprintf(maskFile, "%s%cwater_mask.img", tmpDir, DIR_SEPARATOR); sprintf(latFile, "%s%clatitude.img", tmpDir, DIR_SEPARATOR); sprintf(lonFile, "%s%clongitude.img", tmpDir, DIR_SEPARATOR); sprintf(xFile, "%s%cxgrid.img", tmpDir, DIR_SEPARATOR); sprintf(yFile, "%s%cygrid.img", tmpDir, DIR_SEPARATOR); // Generating output XML file fpInList = FOPEN(listInFile, "r"); fpOutList = FOPEN(listOutFile, "w"); fprintf(fpOutList, "<netcdf>\n"); fprintf(fpOutList, " <data>\n"); fprintf(fpOutList, " <latitude>%s</latitude>\n", latFile); fprintf(fpOutList, " <longitude>%s</longitude>\n", lonFile); fprintf(fpOutList, " <xgrid>%s</xgrid>\n", xFile); fprintf(fpOutList, " <ygrid>%s</ygrid>\n", yFile); fprintf(fpOutList, " <mask>%s</mask>\n", maskFile); julian_date jdStart, jdEnd, jdRef; hms_time hms; hms.hour = 0; hms.min = 0; hms.sec = 0.0; asfPrintStatus("Working through the file list:\n"); int myrFlag=FALSE, divFlag=FALSE, vrtFlag=FALSE, shrFlag=FALSE; int firstYear, firstDay, startYear, startDay, endYear, endDay; double westBoundLon, eastBoundLon, northBoundLat, southBoundLat; double minLat=90.0, maxLat=-90.0, minLon=180.0, maxLon=-180.0; while (fgets(inFile, 512, fpInList)) { chomp(inFile); char inDirName[512], inFileName[512]; split_dir_and_file(inFile, inDirName, inFileName); // Preparing map projection information project_parameters_t pps; projection_type_t proj_type; datum_type_t datum; spheroid_type_t spheroid; read_proj_file("polar_stereographic_north_ssmi.proj", &pps, &proj_type, &datum, &spheroid); pps.ps.false_easting = 0.0; pps.ps.false_northing = 0.0; meta_projection *proj = meta_projection_init(); proj->type = proj_type; proj->datum = HUGHES_DATUM; proj->spheroid = HUGHES_SPHEROID; proj->param = pps; strcpy(proj->units, "meters"); proj->hem = 'N'; spheroid_axes_lengths(spheroid, &proj->re_major, &proj->re_minor); // Sort out dates startYear = subInt(inFileName, 0, 4); startDay = subInt(inFileName, 4, 3); endYear = subInt(inFileName, 8, 4); endDay = subInt(inFileName, 12, 3); if (nFiles == 0) { firstYear = startYear; firstDay = startDay; } sprintf(citation, "%d%03d to %d%03d", startYear, startDay, endYear, endDay); rgps2iso_date(startYear, (double) startDay, start); rgps2iso_date(endYear, (double) endDay, end); rgps2iso_date(firstYear, (double) firstDay, first); // Read header information FILE *fpIn = FOPEN(inFile, "r"); fgets(header, 100, fpIn); sscanf(header, "%f %f %f %f %f %f", &x_pix, &y_pix, &x_map_ll, &y_map_ll, &x_map_ur, &y_map_ur); fgets(header, 100, fpIn); int params = sscanf(header, "%f %f %d %d", &inc, &cat, &sample_count, &line_count); if (params == 3) { sscanf(header, "%f %d %d", &cat, &sample_count, &line_count); inc = 0; } else if (params == 2) { sscanf(header, "%d %d", &sample_count, &line_count); inc = 0; cat = 1; } num = (int) cat; if (num > 1) asfPrintError("Multiband imagery (%s) not supported for netCDF " "generation!\n", inFile); /* printf("x_pix: %f, y_pix: %f\n", x_pix, y_pix); printf("x_map_ll: %f, y_map_ll: %f\n", x_map_ll, y_map_ll); printf("x_map_ur: %f, y_map_ur: %f\n", x_map_ur, y_map_ur); printf("sample_count: %d, line_count: %d\n\n", sample_count, line_count); */ // Check extension split_base_and_ext(inFileName, 1, '.', baseName, ext); asfPrintStatus("Processing %s ...\n", inFileName); sprintf(imgFile, "%s%c%s_%s.img", tmpDir, DIR_SEPARATOR, baseName, &ext[1]); sprintf(metaFile, "%s%c%s_%s.meta", tmpDir, DIR_SEPARATOR, baseName, &ext[1]); jdRef.year = firstYear; jdRef.jd = 1; jdStart.year = startYear; jdStart.jd = startDay; jdEnd.year = endYear; jdEnd.jd = endDay; double startSec = date2sec(&jdStart, &hms) - date2sec(&jdRef, &hms); double endSec = date2sec(&jdEnd, &hms) - date2sec(&jdRef, &hms); if (strcmp_case(ext, ".MYR") == 0) { fprintf(fpOutList, " <multiyear_ice_fraction start=\"%.0f\" end=\"%.0f" "\">%s</multiyear_ice_fraction>\n", startSec, endSec, imgFile); image_data_type = MULTIYEAR_ICE_FRACTION; myrFlag = TRUE; } else if (strcmp_case(ext, ".DIV") == 0) { fprintf(fpOutList, " <divergence start=\"%.0f\" end=\"%.0f\">%s" "</divergence>\n", startSec, endSec, imgFile); image_data_type = DIVERGENCE; divFlag = TRUE; } else if (strcmp_case(ext, ".VRT") == 0) { fprintf(fpOutList, " <vorticity start=\"%.0f\" end=\"%.0f\">%s" "</vorticity>\n", startSec, endSec, imgFile); image_data_type = VORTICITY; vrtFlag = TRUE; } else if (strcmp_case(ext, ".SHR") == 0) { fprintf(fpOutList, " <shear start=\"%.0f\" end=\"%.0f\">%s</shear>", startSec, endSec, imgFile); image_data_type = SHEAR; shrFlag = TRUE; } // Generate basic metadata meta = raw_init(); meta->general->line_count = line_count; meta->general->sample_count = sample_count; meta->general->band_count = 1; meta->general->data_type = REAL32; meta->general->image_data_type = image_data_type; strcpy(meta->general->basename, inFile); meta->general->x_pixel_size = x_pix*1000.0; meta->general->y_pixel_size = y_pix*1000.0; meta->general->start_line = 0; meta->general->start_sample = 0; meta->general->no_data = MAGIC_UNSET_DOUBLE; strcpy(meta->general->sensor, "RGPS MEaSUREs"); char *tmp = image_data_type2str(meta->general->image_data_type); sprintf(meta->general->bands, "%s", lc(tmp)); FREE(tmp); sprintf(meta->general->acquisition_date, "%s", baseName); // Sort out map projection proj->startX = x_map_ll*1000.0; proj->startY = y_map_ur*1000.0; proj->perX = x_pix*1000.0; proj->perY = -y_pix*1000.0; meta->projection = proj; meta_write(meta, metaFile); strcpy(meta->general->bands, "water mask"); sprintf(metaFile, "%s%cwater_mask.meta", tmpDir, DIR_SEPARATOR); meta_write(meta, metaFile); sprintf(metaFile, "%s%c%s_%s.meta", tmpDir, DIR_SEPARATOR, baseName, &ext[1]); float *floatBuf = (float *) MALLOC(sizeof(float)*sample_count); // Write gridded data to ASF internal format fpOut = FOPEN(imgFile, "wb"); for (ii=0; ii<line_count; ii++) { for (kk=0; kk<sample_count; kk++) { ASF_FREAD(&floatBuf[kk], sizeof(float), 1, fpIn); ieee_big32(floatBuf[kk]); if (floatBuf[kk] > 10000000000.0 || FLOAT_EQUIVALENT(floatBuf[kk], 10000000000.0)) floatBuf[kk] = MAGIC_UNSET_DOUBLE; } put_float_line(fpOut, meta, line_count-ii-1, floatBuf); } FCLOSE(fpOut); FREE(floatBuf); double lat1, lon1, lat2, lon2, lat3, lon3, lat4, lon4; proj_to_latlon(proj, x_map_ll*1000.0, y_map_ll*1000.0, 0.0, &lat1, &lon1, &height); proj_to_latlon(proj, x_map_ll*1000.0, y_map_ur*1000.0, 0.0, &lat2, &lon2, &height); proj_to_latlon(proj, x_map_ur*1000.0, y_map_ur*1000.0, 0.0, &lat3, &lon3, &height); proj_to_latlon(proj, x_map_ur*1000.0, y_map_ll*1000.0, 0.0, &lat4, &lon4, &height); westBoundLon = minValue(lon1*R2D, lon2*R2D, lon3*R2D, lon4*R2D); eastBoundLon = maxValue(lon1*R2D, lon2*R2D, lon3*R2D, lon4*R2D); northBoundLat = maxValue(lat1*R2D, lat2*R2D, lat3*R2D, lat4*R2D); southBoundLat = minValue(lat1*R2D, lat2*R2D, lat3*R2D, lat4*R2D); if (westBoundLon < minLon) minLon = westBoundLon; if (eastBoundLon > maxLon) maxLon = eastBoundLon; if (southBoundLat < minLat) minLat = southBoundLat; if (northBoundLat > maxLat) maxLat = northBoundLat; meta_free(meta); nFiles++; } FCLOSE(fpInList); fprintf(fpOutList, " </data>\n"); fprintf(fpOutList, " <metadata>\n"); fprintf(fpOutList, " <time>\n"); fprintf(fpOutList, " <axis type=\"string\" definition=\"name of axis\">T" "</axis>\n"); fprintf(fpOutList, " <long_name type=\"string\" definition=\"long " "descriptive name\">serial date</long_name>\n"); fprintf(fpOutList, " <references type=\"string\" definition=\"reference " "of the value\">start time of 3-day average</references>\n"); fprintf(fpOutList, " <standard_name type=\"string\" definition=\"name " "used to identify the physical quantity\">time</standard_name>\n"); fprintf(fpOutList, " <units type=\"string\" definition=\"unit of " "dimensional quantity\">seconds since %d-01-01T00:00:00Z</units>\n", firstYear); fprintf(fpOutList, " <bounds type=\"string\" definition=\"variable " "containing data range\">time_bounds</bounds>\n"); fprintf(fpOutList, " <FillValue type=\"double\" definition=\"default " "value\">0</FillValue>\n"); fprintf(fpOutList, " </time>\n"); fprintf(fpOutList, " <time_bounds>\n"); fprintf(fpOutList, " <long_name type=\"string\" definition=\"long " "descriptive name\">serial date</long_name>\n"); fprintf(fpOutList, " <references type=\"string\" definition=\"reference " "of the value\">start and end time of 3-day average</references>\n"); fprintf(fpOutList, " <standard_name type=\"string\" definition=\"name " "used to identify the physical quantity\">time</standard_name>\n"); fprintf(fpOutList, " <units type=\"string\" definition=\"unit of " "dimensional quantity\">seconds since %d-01-01T00:00:00Z</units>\n", firstYear); fprintf(fpOutList, " <FillValue type=\"double\" definition=\"default " "value\">0</FillValue>\n"); fprintf(fpOutList, " </time_bounds>\n"); fprintf(fpOutList, " <latitude>\n"); fprintf(fpOutList, " <long_name type=\"string\" definition=\"long " "descriptive name\">latitude</long_name>\n"); fprintf(fpOutList, " <standard_name type=\"string\" definition=\"name " "used to identify the physical quantity\">latitude</standard_name>\n"); fprintf(fpOutList, " <units type=\"string\" definition=\"unit of " "dimensional quantity\">degrees_north</units>\n"); fprintf(fpOutList, " <FillValue type=\"float\" definition=\"default " "value\">-999</FillValue>\n"); fprintf(fpOutList, " <valid_min type=\"float\" definition=\"minimum " "valid value\">-90.0</valid_min>\n"); fprintf(fpOutList, " <valid_max type=\"float\" definition=\"minimum " "valid value\">90.0</valid_max>\n"); fprintf(fpOutList, " </latitude>\n"); fprintf(fpOutList, " <longitude>\n"); fprintf(fpOutList, " <long_name type=\"string\" definition=\"long " "descriptive name\">longitude</long_name>\n"); fprintf(fpOutList, " <standard_name type=\"string\" definition=\"name " "used to identify the physical quantity\">longitude</standard_name>\n"); fprintf(fpOutList, " <units type=\"string\" definition=\"unit of " "dimensional quantity\">degrees_east</units>\n"); fprintf(fpOutList, " <FillValue type=\"float\" definition=\"default " "value\">-999</FillValue>\n"); fprintf(fpOutList, " <valid_min type=\"float\" definition=\"minimum " "valid value\">-180.0</valid_min>\n"); fprintf(fpOutList, " <valid_max type=\"float\" definition=\"minimum " "valid value\">180.0</valid_max>\n"); fprintf(fpOutList, " </longitude>\n"); fprintf(fpOutList, " <xgrid>\n"); fprintf(fpOutList, " <axis type=\"string\" definition=\"name of axis\">X" "</axis>\n"); fprintf(fpOutList, " <long_name type=\"string\" definition=\"long " "descriptive name\">projection_grid_x_center</long_name>\n"); fprintf(fpOutList, " <standard_name type=\"string\" definition=\"name " "used to identify the physical quantity\">projection_x_coordinate" "</standard_name>\n"); fprintf(fpOutList, " <units type=\"string\" definition=\"unit of " "dimensional quantity\">meters</units>\n"); fprintf(fpOutList, " <FillValue type=\"float\" definition=\"default " "value\">NaN</FillValue>\n"); fprintf(fpOutList, " </xgrid>\n"); fprintf(fpOutList, " <ygrid>\n"); fprintf(fpOutList, " <axis type=\"string\" definition=\"name of axis\">Y" "</axis>\n"); fprintf(fpOutList, " <long_name type=\"string\" definition=\"long " "descriptive name\">projection_grid_y_center</long_name>\n"); fprintf(fpOutList, " <standard_name type=\"string\" definition=\"name " "used to identify the physical quantity\">projection_y_coordinate" "</standard_name>\n"); fprintf(fpOutList, " <units type=\"string\" definition=\"unit of " "dimensional quantity\">meters</units>\n"); fprintf(fpOutList, " <FillValue type=\"float\" definition=\"default " "value\">NaN</FillValue>\n"); fprintf(fpOutList, " </ygrid>\n"); fprintf(fpOutList, " <Polar_Stereographic>\n"); fprintf(fpOutList, " <grid_mapping_name>polar_stereographic" "</grid_mapping_name>\n"); fprintf(fpOutList, " <straight_vertical_longitude_from_pole>%.1f" "</straight_vertical_longitude_from_pole>\n", pps.ps.slon); fprintf(fpOutList, " <longitude_of_central_meridian>90.0" "</longitude_of_central_meridian>\n"); fprintf(fpOutList, " <standard_parallel>%.1f</standard_parallel>\n", pps.ps.slat); fprintf(fpOutList, " <false_easting>%.1f</false_easting>\n", pps.ps.false_easting); fprintf(fpOutList, " <false_northing>%.1f</false_northing>\n", pps.ps.false_northing); fprintf(fpOutList, " <projection_x_coordinate>xgrid" "</projection_x_coordinate>\n"); fprintf(fpOutList, " <projection_y_coordinate>ygrid" "</projection_y_coordinate>\n"); fprintf(fpOutList, " <units>meters</units>\n"); fprintf(fpOutList, " </Polar_Stereographic>\n"); fprintf(fpOutList, " <mask>\n"); fprintf(fpOutList, " <coordinates type=\"string\" definition=\"" "coordinate reference\">ygrid xgrid</coordinates>\n"); fprintf(fpOutList, " <grid_mapping type=\"string\" definition=\"\">" "Polar_Stereographic</grid_mapping>\n"); fprintf(fpOutList, " <long_name type=\"string\" definition=\"long " "descriptive name\">projection_grid_y_center</long_name>\n"); fprintf(fpOutList, " <units type=\"string\" definition=\"unit of " "dimensional quantity\">1</units>\n"); fprintf(fpOutList, " <units_description type=\"string\" definition=\"" "descriptive information about dimensionless quantity\">unitless" "</units_description>\n"); fprintf(fpOutList, " <FillValue type=\"int\" definition=\"default " "value\">0</FillValue>\n"); fprintf(fpOutList, " </mask>\n"); if (myrFlag) { fprintf(fpOutList, " <multiyear_ice_fraction>\n"); fprintf(fpOutList, " <cell_methods type=\"string\" definition=\"" "characteristic of a field that is represented by cell values\">area: " "multiyear ice fraction value</cell_methods>\n"); fprintf(fpOutList, " <coordinates type=\"string\" definition=\"" "coordinate reference\">ygrid xgrid</coordinates>\n"); fprintf(fpOutList, " <grid_mapping type=\"string\" definition=\"\">" "Polar_Stereographic</grid_mapping>\n"); fprintf(fpOutList, " <long_name type=\"string\" definition=\"long " "descriptive name\">RGPS MEaSUREs multiyear ice fraction</long_name>\n"); fprintf(fpOutList, " <units type=\"string\" definition=\"unit of " "dimensional quantity\">1</units>\n"); fprintf(fpOutList, " <units_description type=\"string\" definition=\"" "descriptive information about dimensionless quantity\">unitless" "</units_description>\n"); fprintf(fpOutList, " <FillValue type=\"float\" definition=\"default " "value\">NaN</FillValue>\n"); fprintf(fpOutList, " </multiyear_ice_fraction>\n"); } if (divFlag) { fprintf(fpOutList, " <divergence>\n"); fprintf(fpOutList, " <cell_methods type=\"string\" definition=\"" "characteristic of a field that is represented by cell values\">area: " "divergence value</cell_methods>\n"); fprintf(fpOutList, " <coordinates type=\"string\" definition=\"" "coordinate reference\">ygrid xgrid</coordinates>\n"); fprintf(fpOutList, " <grid_mapping type=\"string\" definition=\"\">" "Polar_Stereographic</grid_mapping>\n"); fprintf(fpOutList, " <long_name type=\"string\" definition=\"long " "descriptive name\">RGPS MEaSUREs divergence</long_name>\n"); fprintf(fpOutList, " <units type=\"string\" definition=\"unit of " "dimensional quantity\">1</units>\n"); fprintf(fpOutList, " <units_description type=\"string\" definition=\"" "descriptive information about dimensionless quantity\">unitless" "</units_description>\n"); fprintf(fpOutList, " <FillValue type=\"float\" definition=\"default " "value\">NaN</FillValue>\n"); fprintf(fpOutList, " </divergence>\n"); } if (vrtFlag) { fprintf(fpOutList, " <vorticity>\n"); fprintf(fpOutList, " <cell_methods type=\"string\" definition=\"" "characteristic of a field that is represented by cell values\">area: " "vorticity value</cell_methods>\n"); fprintf(fpOutList, " <coordinates type=\"string\" definition=\"" "coordinate reference\">ygrid xgrid</coordinates>\n"); fprintf(fpOutList, " <grid_mapping type=\"string\" definition=\"\">" "Polar_Stereographic</grid_mapping>\n"); fprintf(fpOutList, " <long_name type=\"string\" definition=\"long " "descriptive name\">RGPS MEaSUREs vorticity</long_name>\n"); fprintf(fpOutList, " <units type=\"string\" definition=\"unit of " "dimensional quantity\">1</units>\n"); fprintf(fpOutList, " <units_description type=\"string\" definition=\"" "descriptive information about dimensionless quantity\">unitless" "</units_description>\n"); fprintf(fpOutList, " <FillValue type=\"float\" definition=\"default " "value\">NaN</FillValue>\n"); fprintf(fpOutList, " </vorticity>\n"); } if (shrFlag) { fprintf(fpOutList, " <shear>\n"); fprintf(fpOutList, " <cell_methods type=\"string\" definition=\"" "characteristic of a field that is represented by cell values\">area: " "shear value</cell_methods>\n"); fprintf(fpOutList, " <coordinates type=\"string\" definition=\"" "coordinate reference\">ygrid xgrid</coordinates>\n"); fprintf(fpOutList, " <grid_mapping type=\"string\" definition=\"\">" "Polar_Stereographic</grid_mapping>\n"); fprintf(fpOutList, " <long_name type=\"string\" definition=\"long " "descriptive name\">RGPS MEaSUREs shear</long_name>\n"); fprintf(fpOutList, " <units type=\"string\" definition=\"unit of " "dimensional quantity\">1</units>\n"); fprintf(fpOutList, " <units_description type=\"string\" definition=\"" "descriptive information about dimensionless quantity\">unitless" "</units_description>\n"); fprintf(fpOutList, " <FillValue type=\"float\" definition=\"default " "value\">NaN</FillValue>\n"); fprintf(fpOutList, " </shear>\n"); } fprintf(fpOutList, " </metadata>\n"); fprintf(fpOutList, " <parameter>\n"); if (myrFlag) fprintf(fpOutList, " <multiyear_ice_fraction type=\"float\"/>\n"); if (divFlag) fprintf(fpOutList, " <divergence type=\"float\"/>\n"); if (vrtFlag) fprintf(fpOutList, " <vorticity type=\"float\"/>\n"); if (shrFlag) fprintf(fpOutList, " <shear type=\"float\"/>\n"); fprintf(fpOutList, " </parameter>\n"); char startStr[15], endStr[15]; jdStart.year = firstYear; jdStart.jd = firstDay; jdEnd.year = endYear; jdEnd.jd = endDay; jd2date(&jdStart, startStr); jd2date(&jdEnd, endStr); if (firstYear != endYear || firstDay != endDay) sprintf(citation, "%s to %s", startStr, endStr); else sprintf(citation, "%s", startStr); fprintf(fpOutList, " <root>\n"); fprintf(fpOutList, " <Conventions>CF-1.6</Conventions>\n"); fprintf(fpOutList, " <institution>Alaska Satellite Facility</institution>\n"); fprintf(fpOutList, " <title>Kwok, Ron. 2008. MEaSUREs Small-Scale Kinematics" " of Arctic Ocean Sea Ice, Version 01, %s. Jet Propulsion Laboratory " "Pasadena, CA USA and Alaska Satellite Facility Fairbanks, AK USA. " "Digital media.</title>\n", citation); fprintf(fpOutList, " <source>Products derived from RADARSAT-1 SWB imagery at " "100 m resolution</source>\n"); fprintf(fpOutList, " <comment>Imagery the products are derived from: Copyright " "Canadian Space Agency (1996 to 2008)</comment>\n"); fprintf(fpOutList, " <reference>Documentation available at: www.asf.alaska.edu" "</reference>\n"); fprintf(fpOutList, " <history>%s: netCDF file created.</history>\n", isoStr); fprintf(fpOutList, " </root>\n"); fprintf(fpOutList, "</netcdf>\n"); FCLOSE(fpOutList); // Generate supplemental files: water mask, lat/lon, x/y grids asfPrintStatus("Generating supplemental files ...\n"); float *floatBuf = (float *) MALLOC(sizeof(float)*sample_count); float *maskBuf = (float *) MALLOC(sizeof(float)*sample_count); float *latBuf = (float *) MALLOC(sizeof(float)*sample_count); float *lonBuf = (float *) MALLOC(sizeof(float)*sample_count); float *xBuf = (float *) MALLOC(sizeof(float)*sample_count); float *yBuf = (float *) MALLOC(sizeof(float)*sample_count); meta = meta_read(metaFile); fpIn = FOPEN(inFile, "r"); fgets(header, 100, fpIn); sscanf(header, "%f %f %f %f %f %f", &x_pix, &y_pix, &x_map_ll, &y_map_ll, &x_map_ur, &y_map_ur); fgets(header, 100, fpIn); sscanf(header, "%d %d", &sample_count, &line_count); FILE *fpMask = FOPEN(maskFile, "wb"); FILE *fpLat = FOPEN(latFile, "wb"); FILE *fpLon = FOPEN(lonFile, "wb"); FILE *fpXgrid = FOPEN(xFile, "wb"); FILE *fpYgrid = FOPEN(yFile, "wb"); for (ii=0; ii<line_count; ii++) { for (kk=0; kk<sample_count; kk++) { ASF_FREAD(&floatBuf[kk], sizeof(float), 1, fpIn); ieee_big32(floatBuf[kk]); } for (kk=0; kk<sample_count; kk++) { meta_get_latLon(meta, line_count-ii-1, kk, 0.0, &lat, &lon); latlon_to_proj(meta->projection, 'R', lat*D2R, lon*D2R, 0.0, &x, &y, &z); latBuf[kk] = lat; lonBuf[kk] = lon; xBuf[kk] = x; yBuf[kk] = y; if (floatBuf[kk] < 10000000000.0) { maskBuf[kk] = 1.0; } else if (floatBuf[kk] > 10000000000.0) { maskBuf[kk] = 1.0; } else { maskBuf[kk] = 0.0; } } put_float_line(fpMask, meta, line_count-ii-1, maskBuf); put_float_line(fpLat, meta, line_count-ii-1, latBuf); put_float_line(fpLon, meta, line_count-ii-1, lonBuf); put_float_line(fpXgrid, meta, line_count-ii-1, xBuf); put_float_line(fpYgrid, meta, line_count-ii-1, yBuf); } FCLOSE(fpIn); FCLOSE(fpMask); FCLOSE(fpLat); FCLOSE(fpLon); FREE(floatBuf); FREE(maskBuf); FREE(latBuf); FREE(lonBuf); FREE(xBuf); FREE(yBuf); meta_write(meta, latFile); meta_write(meta, lonFile); meta_write(meta, xFile); meta_write(meta, yFile); // Write ISO meatadata for netCDF asfPrintStatus("Generating metadata for netCDF file ...\n"); char *ncXmlBase = get_basename(outFile); char *ncXmlFile = appendExt(outFile, ".xml"); fpXml = FOPEN(ncXmlFile, "w"); fprintf(fpXml, "<rgps>\n"); fprintf(fpXml, " <granule>%s</granule>\n", ncXmlBase); fprintf(fpXml, " <metadata_creation>%s</metadata_creation>\n", isoStr); fprintf(fpXml, " <metadata>\n"); fprintf(fpXml, " <product>\n"); fprintf(fpXml, " <file type=\"string\" definition=\"name of product " "file\">%s.nc</file>\n", ncXmlBase); if (divFlag && vrtFlag && shrFlag) fprintf(fpXml, " <type type=\"string\" definition=\"product type\">" "divergence, vorticity, shear</type>\n"); else if (myrFlag) fprintf(fpXml, " <type type=\"string\" definition=\"product type\">" "multiyear ice fraction</type>\n"); fprintf(fpXml, " <format type=\"string\" definition=\"name of the data " "format\">netCDF</format>\n"); fpInList = FOPEN(listInFile, "r"); while (fgets(inFile, 512, fpInList)) { chomp(inFile); split_dir_and_file(inFile, dirName, baseName); fprintf(fpXml, " <source type=\"string\" definition=\"name of the data" " source\">%s</source>\n", baseName); } FCLOSE(fpInList); fprintf(fpXml, " <cell_size_x type=\"double\" definition=\"cell size " "in x direction\" units=\"m\">%.2f</cell_size_x>\n", x_pix*1000.0); fprintf(fpXml, " <cell_size_y type=\"double\" definition=\"cell size " "in y direction\" units=\"m\">%.2f</cell_size_y>\n", y_pix*1000.0); fprintf(fpXml, " <map_x_lower_left type=\"double\" definition=\"x " "coordinate of lower left corner\" units=\"m\">%.6f</map_x_lower_left>\n", x_map_ll*1000.0); fprintf(fpXml, " <map_y_lower_left type=\"double\" definition=\"y " "coordinate of lower left corner\" units=\"m\">%.6f</map_y_lower_left>\n", y_map_ll*1000.0); fprintf(fpXml, " <map_x_upper_right type=\"double\" definition=\"x " "coordinate of upper right corner\" units=\"m\">%.6f</map_x_upper_right>" "\n", x_map_ur*1000.0); fprintf(fpXml, " <map_y_upper_right type=\"double\" definition=\"y " "coordinate of upper right corner\" units=\"m\">%.6f</map_y_upper_right>" "\n", y_map_ur*1000.0); fprintf(fpXml, " <cell_dimension_x type=\"int\" definition=\"cell " "dimension in x direction\">%d</cell_dimension_x>\n", sample_count); fprintf(fpXml, " <cell_dimension_y type=\"int\" definition=\"cell " "dimension in y direction\">%d</cell_dimension_y>\n", line_count); fprintf(fpXml, " <projection_string type=\"string\" definition=\"map " "projection information as well known text\">%s</projection_string>\n", meta2esri_proj(meta, NULL)); fprintf(fpXml, " </product>\n"); fprintf(fpXml, " </metadata>\n"); fprintf(fpXml, " <extent>\n"); fprintf(fpXml, " <product>\n"); fprintf(fpXml, " <westBoundLongitude>%.5f</westBoundLongitude>\n", minLon); fprintf(fpXml, " <eastBoundLongitude>%.5f</eastBoundLongitude>\n", maxLon); fprintf(fpXml, " <northBoundLatitude>%.5f</northBoundLatitude>\n", maxLat); fprintf(fpXml, " <southBoundLatitude>%.5f</southBoundLatitude>\n", minLat); fprintf(fpXml, " <start_datetime>%s</start_datetime>\n", first); fprintf(fpXml, " <end_datetime>%s</end_datetime>\n", end); fprintf(fpXml, " </product>\n"); fprintf(fpXml, " </extent>\n"); fprintf(fpXml, "</rgps>\n"); FCLOSE(fpXml); FREE(ncXmlBase); FREE(ncXmlFile); meta_free(meta); // Export to netCDF asfPrintStatus("Exporting to netCDF file ...\n"); export_netcdf_xml(listOutFile, outFile); // Clean up remove_dir(tmpDir); FREE(tmpDir); FREE(outFile); FREE(listInFile); FREE(isoStr); return 0; }
static void get_inner_extents(char *file, double *x0, double *y0, double *xL, double *yL) { int ii, kk; FILE *fp = FOPEN(file, "rb"); meta_parameters *meta = meta_read(file); int line_count = meta->general->line_count; int sample_count = meta->general->sample_count; int startX = sample_count - 1; int endX = 0; int startY = -99; int endY = -99; int startLine = -99; int startSample = -99; int endLine = 0; int endSample = 0; float *buf = (float *) MALLOC(sizeof(float)*sample_count); for (ii=0; ii<line_count; ii++) { get_float_line(fp, meta, ii, buf); int left = 0; int right = sample_count - 1; while (FLOAT_EQUIVALENT(buf[left], 0.0) && left < sample_count - 1) left++; while (FLOAT_EQUIVALENT(buf[right], 0.0) && right > 0) right--; if (left < startX) { startX = left; startLine = ii; } if (right > endX) { endX = right; endLine = ii; } int all_zero = TRUE; for (kk=0; kk<sample_count; kk++) { if (!FLOAT_EQUIVALENT(buf[kk], 0.0)) { all_zero = FALSE; break; } } if (!all_zero) { if (startY < 0) { startY = ii; endSample = kk; } startSample = kk; endY = ii; } } FCLOSE(fp); FREE(buf); *x0 = meta->projection->startX + startSample*meta->projection->perX; *y0 = meta->projection->startY + startLine*meta->projection->perY; *xL = meta->projection->startX + endSample*meta->projection->perX; *yL = meta->projection->startY + endLine*meta->projection->perY; meta_free(meta); }
int asf_igram_coh(int lookLine, int lookSample, int stepLine, int stepSample, char *masterFile, char *slaveFile, char *outBase, float *average) { char ampFile[255], phaseFile[255]; //, igramFile[512]; char cohFile[512], ml_ampFile[255], ml_phaseFile[255]; //, ml_igramFile[512]; FILE *fpMaster, *fpSlave, *fpAmp, *fpPhase, *fpCoh, *fpAmp_ml, *fpPhase_ml; int line, sample_count, line_count, count; float bin_high, bin_low, max=0.0, sum_a, sum_b, ampScale; double hist_sum=0.0, percent, percent_sum; long long hist_val[HIST_SIZE], hist_cnt=0; meta_parameters *inMeta,*outMeta, *ml_outMeta; complexFloat *master, *slave, *sum_igram, *sum_ml_igram; float *amp, *phase, *sum_cpx_a, *sum_cpx_b, *coh, *pCoh; float *ml_amp, *ml_phase; // FIXME: Processing flow with two-banded interferogram needed - backed out // for now create_name(ampFile, outBase,"_igram_amp.img"); create_name(phaseFile, outBase,"_igram_phase.img"); create_name(ml_ampFile, outBase,"_igram_ml_amp.img"); create_name(ml_phaseFile, outBase,"_igram_ml_phase.img"); //create_name(igramFile, outBase,"_igram.img"); //create_name(ml_igramFile, outBase, "_igram_ml.img"); //sprintf(cohFile, "coherence.img"); create_name(cohFile, outBase, "_coh.img"); // Read input meta file inMeta = meta_read(masterFile); line_count = inMeta->general->line_count; sample_count = inMeta->general->sample_count; ampScale = 1.0/(stepLine*stepSample); // Generate metadata for single-look images outMeta = meta_read(masterFile); outMeta->general->data_type = REAL32; // Write metadata for interferometric amplitude outMeta->general->image_data_type = AMPLITUDE_IMAGE; meta_write(outMeta, ampFile); // Write metadata for interferometric phase outMeta->general->image_data_type = PHASE_IMAGE; meta_write(outMeta, phaseFile); /* // Write metadata for interferogram outMeta->general->image_data_type = INTERFEROGRAM; outMeta->general->band_count = 2; strcpy(outMeta->general->bands, "IGRAM-AMP,IGRAM-PHASE"); meta_write(outMeta, igramFile); */ // Generate metadata for multilooked images ml_outMeta = meta_read(masterFile); ml_outMeta->general->data_type = REAL32; ml_outMeta->general->line_count = line_count/stepLine; ml_outMeta->general->sample_count = sample_count/stepSample; ml_outMeta->general->x_pixel_size *= stepSample; ml_outMeta->general->y_pixel_size *= stepLine; ml_outMeta->sar->multilook = 1; ml_outMeta->sar->line_increment *= stepLine; ml_outMeta->sar->sample_increment *= stepSample; // FIXME: This is the wrong increment but create_dem_grid does not know any // better at the moment. //ml_outMeta->sar->line_increment = 1; //ml_outMeta->sar->sample_increment = 1; // Write metadata for multilooked interferometric amplitude ml_outMeta->general->image_data_type = AMPLITUDE_IMAGE; meta_write(ml_outMeta, ml_ampFile); // Write metadata for multilooked interferometric phase ml_outMeta->general->image_data_type = PHASE_IMAGE; meta_write(ml_outMeta, ml_phaseFile); // Write metadata for coherence image ml_outMeta->general->image_data_type = COHERENCE_IMAGE; meta_write(ml_outMeta, cohFile); /* // Write metadata for multilooked interferogram ml_outMeta->general->image_data_type = INTERFEROGRAM; strcpy(ml_outMeta->general->bands, "IGRAM-AMP,IGRAM-PHASE"); ml_outMeta->general->band_count = 2; meta_write(ml_outMeta, ml_igramFile); */ // Allocate memory master = (complexFloat *) MALLOC(sizeof(complexFloat)*sample_count*lookLine); slave = (complexFloat *) MALLOC(sizeof(complexFloat)*sample_count*lookLine); amp = (float *) MALLOC(sizeof(float)*sample_count*lookLine); phase = (float *) MALLOC(sizeof(float)*sample_count*lookLine); ml_amp = (float *) MALLOC(sizeof(float)*sample_count/stepSample); ml_phase = (float *) MALLOC(sizeof(float)*sample_count/stepSample); coh = (float *) MALLOC(sizeof(float)*sample_count/stepSample); sum_cpx_a = (float *) MALLOC(sizeof(float)*sample_count); sum_cpx_b = (float *) MALLOC(sizeof(float)*sample_count); sum_igram = (complexFloat *) MALLOC(sizeof(complexFloat)*sample_count); sum_ml_igram = (complexFloat *) MALLOC(sizeof(complexFloat)*sample_count); // Open files fpMaster = FOPEN(masterFile,"rb"); fpSlave = FOPEN(slaveFile,"rb"); fpAmp = FOPEN(ampFile,"wb"); fpPhase = FOPEN(phaseFile,"wb"); fpAmp_ml = FOPEN(ml_ampFile,"wb"); fpPhase_ml = FOPEN(ml_phaseFile,"wb"); //FILE *fpIgram = FOPEN(igramFile, "wb"); //FILE *fpIgram_ml = FOPEN(ml_igramFile, "wb"); fpCoh = FOPEN(cohFile,"wb"); // Initialize histogram for (count=0; count<HIST_SIZE; count++) hist_val[count] = 0; asfPrintStatus(" Calculating interferogram and coherence ...\n\n"); for (line=0; line<line_count; line+=stepLine) { register int offset, row, column, limitLine; double igram_real, igram_imag; int inCol; limitLine=MIN(lookLine, line_count-line); printf("Percent completed %3.0f\r",(float)line/line_count*100.0); pCoh = coh; // Read in the next lines of data get_complexFloat_lines(fpMaster, inMeta, line, limitLine, master); get_complexFloat_lines(fpSlave, inMeta, line, limitLine, slave); // Add the remaining rows into sum vectors offset = sample_count; for (column=0; column<sample_count; column++) { offset = column; sum_cpx_a[column] = 0.0; sum_cpx_b[column] = 0.0; sum_igram[column].real = 0.0; sum_igram[column].imag = 0.0; sum_ml_igram[column].real = 0.0; sum_ml_igram[column].imag = 0.0; igram_real = 0.0; igram_imag = 0.0; for (row=0; row<limitLine; row++) { // Complex multiplication for interferogram generation igram_real = master[offset].real*slave[offset].real + master[offset].imag*slave[offset].imag; igram_imag = master[offset].imag*slave[offset].real - master[offset].real*slave[offset].imag; amp[offset] = sqrt(igram_real*igram_real + igram_imag*igram_imag); if (FLOAT_EQUIVALENT(igram_real, 0.0) || FLOAT_EQUIVALENT(igram_imag, 0.0)) phase[offset]=0.0; else phase[offset] = atan2(igram_imag, igram_real); sum_cpx_a[column] += AMP(master[offset])*AMP(master[offset]); sum_cpx_b[column] += AMP(slave[offset])*AMP(slave[offset]); sum_igram[column].real += igram_real; sum_igram[column].imag += igram_imag; if (line % stepLine == 0 && row < stepLine) { sum_ml_igram[column].real += igram_real; sum_ml_igram[column].imag += igram_imag; } offset += sample_count; } ml_amp[column] = sqrt(sum_ml_igram[column].real*sum_ml_igram[column].real + sum_ml_igram[column].imag*sum_ml_igram[column].imag)*ampScale; if (FLOAT_EQUIVALENT(sum_ml_igram[column].real, 0.0) || FLOAT_EQUIVALENT(sum_ml_igram[column].imag, 0.0)) ml_phase[column] = 0.0; else ml_phase[column] = atan2(sum_ml_igram[column].imag, sum_ml_igram[column].real); } // Write single-look and multilooked amplitude and phase put_float_lines(fpAmp, outMeta, line, stepLine, amp); put_float_lines(fpPhase, outMeta, line, stepLine, phase); put_float_line(fpAmp_ml, ml_outMeta, line/stepLine, ml_amp); put_float_line(fpPhase_ml, ml_outMeta, line/stepLine, ml_phase); //put_band_float_lines(fpIgram, outMeta, 0, line, stepLine, amp); //put_band_float_lines(fpIgram, outMeta, 1, line, stepLine, phase); //put_band_float_line(fpIgram_ml, ml_outMeta, 0, line/stepLine, ml_amp); //put_band_float_line(fpIgram_ml, ml_outMeta, 1, line/stepLine, ml_phase); // Calculate the coherence by adding from sum vectors for (inCol=0; inCol<sample_count; inCol+=stepSample) { register int limitSample = MIN(lookSample,sample_count-inCol); sum_a = 0.0; sum_b = 0.0; igram_real = 0.0; igram_imag = 0.0; // Step over multilook area and sum output columns for (column=0; column<limitSample; column++) { igram_real += sum_igram[inCol+column].real; igram_imag += sum_igram[inCol+column].imag; sum_a += sum_cpx_a[inCol+column]; sum_b += sum_cpx_b[inCol+column]; } if (FLOAT_EQUIVALENT((sum_a*sum_b), 0.0)) *pCoh = 0.0; else { *pCoh = (float) sqrt(igram_real*igram_real + igram_imag*igram_imag) / sqrt(sum_a * sum_b); if (*pCoh>1.0001) { printf(" coh = %f -- setting to 1.0\n",*pCoh); printf(" You shouldn't have seen this!\n"); printf(" Exiting.\n"); exit(EXIT_FAILURE); *pCoh=1.0; } } pCoh++; } // Write out values for coherence put_float_line(fpCoh, ml_outMeta, line/stepLine, coh); // Keep filling coherence histogram for (count=0; count<sample_count/stepSample; count++) { register int tmp; tmp = (int) (coh[count]*HIST_SIZE); /* Figure out which bin this value is in */ /* This shouldn't happen */ if(tmp >= HIST_SIZE) tmp = HIST_SIZE-1; if(tmp < 0) tmp = 0; hist_val[tmp]++; // Increment that bin for the histogram hist_sum += coh[count]; // Add up the values for the sum hist_cnt++; // Keep track of the total number of values if (coh[count]>max) max = coh[count]; // Calculate maximum coherence } } // End for line printf("Percent completed %3.0f\n",(float)line/line_count*100.0); // Sum and print the statistics percent_sum = 0.0; printf(" Coherence : Occurrences : Percent\n"); printf(" ---------------------------------------\n"); for (count=0; count<HIST_SIZE; count++) { bin_low = (float)(count)/(float)HIST_SIZE; bin_high = (float)(count+1)/(float)HIST_SIZE; percent = (double)hist_val[count]/(double)hist_cnt; percent_sum += (float)100*percent; printf(" %.2f -> %.2f : %.8lld %2.3f \n", bin_low,bin_high, (long long) hist_val[count],100*percent); } *average = (float)hist_sum/(float)hist_cnt; printf(" ---------------------------------------\n"); printf(" Maximum Coherence: %.3f\n", max); printf(" Average Coherence: %.3f (%.1f / %lld) %f\n", *average,hist_sum, hist_cnt, percent_sum); // Free and exit FREE(master); FREE(slave); FREE(amp); FREE(phase); FREE(ml_amp); FREE(ml_phase); FREE(coh); FCLOSE(fpMaster); FCLOSE(fpSlave); FCLOSE(fpAmp); FCLOSE(fpPhase); FCLOSE(fpAmp_ml); FCLOSE(fpPhase_ml); //FCLOSE(fpIgram); //FCLOSE(fpIgram_ml); FCLOSE(fpCoh); meta_free(inMeta); meta_free(outMeta); meta_free(ml_outMeta); return(0); }
int asf_calibrate(const char *inFile, const char *outFile, radiometry_t outRadiometry, int wh_scaleFlag) { meta_parameters *metaIn = meta_read(inFile); meta_parameters *metaOut = meta_read(inFile); if (!metaIn->calibration) { asfPrintError("This data cannot be calibrated, missing calibration block.\n"); } // Check for valid output radiometry if (outRadiometry == r_AMP || outRadiometry == r_POWER) asfPrintError("Invalid radiometry (%s) passed into calibration function!\n", radiometry2str(outRadiometry)); // Check whether output radiometry fits with Woods Hole scaling flag if (wh_scaleFlag && outRadiometry >= r_SIGMA && outRadiometry <= r_GAMMA) outRadiometry += 3; // This can only work if the image is in some SAR geometry if (metaIn->projection && metaIn->projection->type != SCANSAR_PROJECTION) asfPrintError("Can't apply calibration factors to map projected images\n" "(Amplitude or Power only)\n"); radiometry_t inRadiometry = metaIn->general->radiometry; asfPrintStatus("Calibrating %s image to %s image\n\n", radiometry2str(inRadiometry), radiometry2str(outRadiometry)); // FIXME: This function should be able to remap between different // radiometry projections. if (metaIn->general->radiometry != r_AMP) asfPrintError("Currently only AMPLITUDE as radiometry is supported!\n"); metaOut->general->radiometry = outRadiometry; int dbFlag = FALSE; if (outRadiometry >= r_SIGMA && outRadiometry <= r_GAMMA) metaOut->general->no_data = 0.0001; if (outRadiometry >= r_SIGMA_DB && outRadiometry <= r_GAMMA_DB) { metaOut->general->no_data = -40.0; dbFlag = TRUE; } if (metaIn->general->image_data_type != POLARIMETRIC_IMAGE) { if (outRadiometry == r_SIGMA || outRadiometry == r_SIGMA_DB) metaOut->general->image_data_type = SIGMA_IMAGE; else if (outRadiometry == r_BETA || outRadiometry == r_BETA_DB) metaOut->general->image_data_type = BETA_IMAGE; else if (outRadiometry == r_GAMMA || outRadiometry == r_GAMMA_DB) metaOut->general->image_data_type = GAMMA_IMAGE; } if (wh_scaleFlag) metaOut->general->data_type = ASF_BYTE; char *input = appendExt(inFile, ".img"); char *output = appendExt(outFile, ".img"); FILE *fpIn = FOPEN(input, "rb"); FILE *fpOut = FOPEN(output, "wb"); int dualpol = strncmp_case(metaIn->general->mode, "FBD", 3) == 0 ? 1 : 0; int band_count = metaIn->general->band_count; int sample_count = metaIn->general->sample_count; int line_count = metaIn->general->line_count; char **bands = extract_band_names(metaIn->general->bands, band_count); float *bufIn = (float *) MALLOC(sizeof(float)*sample_count); float *bufOut = (float *) MALLOC(sizeof(float)*sample_count); float *bufIn2 = NULL, *bufOut2 = NULL, *bufOut3 = NULL; if (dualpol && wh_scaleFlag) { bufIn2 = (float *) MALLOC(sizeof(float)*sample_count); bufOut2 = (float *) MALLOC(sizeof(float)*sample_count); bufOut3 = (float *) MALLOC(sizeof(float)*sample_count); metaOut->general->band_count = 3; sprintf(metaOut->general->bands, "%s,%s,%s-%s", bands[0], bands[1], bands[0], bands[1]); } int ii, jj, kk; float cal_dn, cal_dn2; double incid; if (dualpol && wh_scaleFlag) { metaOut->general->image_data_type = RGB_STACK; for (ii=0; ii<line_count; ii++) { get_band_float_line(fpIn, metaIn, 0, ii, bufIn); get_band_float_line(fpIn, metaIn, 1, ii, bufIn2); for (jj=0; jj<sample_count; jj++) { // Taking the remapping of other radiometries out for the moment //if (inRadiometry >= r_SIGMA && inRadiometry <= r_BETA_DB) //bufIn[jj] = cal2amp(metaIn, incid, jj, bands[kk], bufIn[jj]); incid = meta_incid(metaIn, ii, jj); cal_dn = get_cal_dn(metaOut, incid, jj, bufIn[jj], bands[0], dbFlag); cal_dn2 = get_cal_dn(metaOut, incid, jj, bufIn2[jj], bands[1], dbFlag); if (FLOAT_EQUIVALENT(cal_dn, metaIn->general->no_data) || cal_dn == cal_dn2) { bufOut[jj] = 0; bufOut2[jj] = 0; bufOut3[jj] = 0; } else { bufOut[jj] = (cal_dn + 31) / 0.15 + 1.5; bufOut2[jj] = (cal_dn2 + 31) / 0.15 + 1.5; bufOut3[jj] = bufOut[jj] - bufOut2[jj]; } } put_band_float_line(fpOut, metaOut, 0, ii, bufOut); put_band_float_line(fpOut, metaOut, 1, ii, bufOut2); put_band_float_line(fpOut, metaOut, 2, ii, bufOut3); asfLineMeter(ii, line_count); } } else { for (kk=0; kk<band_count; kk++) { for (ii=0; ii<line_count; ii++) { get_band_float_line(fpIn, metaIn, kk, ii, bufIn); for (jj=0; jj<sample_count; jj++) { // Taking the remapping of other radiometries out for the moment //if (inRadiometry >= r_SIGMA && inRadiometry <= r_BETA_DB) //bufIn[jj] = cal2amp(metaIn, incid, jj, bands[kk], bufIn[jj]); if (strstr(bands[kk], "PHASE") == NULL) { incid = meta_incid(metaIn, ii, jj); cal_dn = get_cal_dn(metaOut, incid, jj, bufIn[jj], bands[kk], dbFlag); if (wh_scaleFlag) { if (FLOAT_EQUIVALENT(cal_dn, metaIn->general->no_data)) bufOut[jj] = 0; else bufOut[jj] = (cal_dn + 31) / 0.15 + 1.5; } else bufOut[jj] = cal_dn; } else // PHASE band, do nothing bufOut[jj] = bufIn[jj]; } put_band_float_line(fpOut, metaOut, kk, ii, bufOut); asfLineMeter(ii, line_count); } if (kk==0) sprintf(metaOut->general->bands, "%s-%s", radiometry2str(outRadiometry), bands[kk]); else { char tmp[255]; sprintf(tmp, ",%s-%s", radiometry2str(outRadiometry), bands[kk]); strcat(metaOut->general->bands, tmp); } } } meta_write(metaOut, outFile); meta_free(metaIn); meta_free(metaOut); FREE(bufIn); FREE(bufOut); if (dualpol) { FREE(bufIn2); FREE(bufOut2); FREE(bufOut3); } for (kk=0; kk<band_count; ++kk) FREE(bands[kk]); FREE(bands); FCLOSE(fpIn); FCLOSE(fpOut); FREE(input); FREE(output); return FALSE; }
void calc_stats_from_file_with_formula(const char *inFile, char *bands, calc_stats_formula_t formula_callback, double mask, double *min, double *max, double *mean, double *stdDev, gsl_histogram **histogram) { int ii,jj,kk; const int N=MAX_BANDS; *min = 999999; *max = -999999; *mean = 0.0; meta_parameters *meta = meta_read(inFile); int band_numbers[N]; for (ii=0; ii<N; ++ii) band_numbers[ii] = -1; int band_count = 0; if (bands) { char *s = STRDUP(bands); // a copy we can fiddle with char *q, *p = s; do { q = strchr(p, ','); if (q) *q = '\0'; if (strlen(p) > 0 && strcmp(p, "???") != 0) { band_numbers[band_count] = get_band_number(meta->general->bands, meta->general->band_count, p); //printf("%s -> %d\n", p, band_numbers[band_count]); ++band_count; } if (q) p = q+1; } while (q); FREE(s); } long band_offsets[N]; float *band_data[N]; for (ii=0; ii<N; ++ii) { if (band_numbers[ii] >= 0) { band_offsets[ii] = meta->general->line_count * band_numbers[ii]; band_data[ii] = MALLOC(sizeof(float)*meta->general->sample_count); } else { band_offsets[ii] = -1; band_data[ii] = NULL; } } // pass 1 -- calculate mean, min & max FILE *fp = FOPEN(inFile, "rb"); long long pixel_count=0; asfPrintStatus("\nCalculating min, max, and mean...\n"); for (ii=0; ii<meta->general->line_count; ++ii) { asfPercentMeter((double)ii/(double)meta->general->line_count); for (kk=0; kk<N; ++kk) { if (band_data[kk]) { assert(band_offsets[kk] >= 0); get_float_line(fp, meta, ii + band_offsets[kk], band_data[kk]); } } for (jj=0; jj<meta->general->sample_count; ++jj) { int is_masked = FALSE; if (ISNAN(mask)) { for (kk=0; kk<N; ++kk) if (band_data[kk] && FLOAT_EQUIVALENT(band_data[kk][jj], mask)) is_masked = TRUE; } if (!is_masked) { double data_arr[N]; int ll; for (ll=0, kk=0; kk<N; ++kk) if (band_data[kk]) data_arr[ll++] = band_data[kk][jj]; assert(ll==band_count); double val = formula_callback(data_arr, mask); if (val < *min) *min = val; if (val > *max) *max = val; *mean += val; ++pixel_count; } } } asfPercentMeter(1.0); FCLOSE(fp); *mean /= pixel_count; // Guard against weird data if(!(*min<*max)) *max = *min + 1; // Initialize the histogram. const int num_bins = 256; gsl_histogram *hist = gsl_histogram_alloc (num_bins); gsl_histogram_set_ranges_uniform (hist, *min, *max); *stdDev = 0.0; // pass 2 -- update histogram, calculate standard deviation fp = FOPEN(inFile, "rb"); asfPrintStatus("\nCalculating standard deviation and histogram...\n"); for (ii=0; ii<meta->general->line_count; ++ii) { asfPercentMeter((double)ii/(double)meta->general->line_count); for (kk=0; kk<N; ++kk) { if (band_data[kk]) { assert(band_offsets[kk] >= 0); get_float_line(fp, meta, ii + band_offsets[kk], band_data[kk]); } } for (jj=0; jj<meta->general->sample_count; ++jj) { int is_masked = FALSE; if (ISNAN(mask)) { for (kk=0; kk<N; ++kk) if (band_data[kk] && FLOAT_EQUIVALENT(band_data[kk][jj], mask)) is_masked = TRUE; } if (!is_masked) { double data_arr[N]; int ll; for (ll=0, kk=0; kk<N; ++kk) if (band_data[kk]) data_arr[ll++] = band_data[kk][jj]; assert(ll==band_count); double val = formula_callback(data_arr, mask); *stdDev += (val - *mean) * (val - *mean); gsl_histogram_increment (hist, val); } } } asfPercentMeter(1.0); FCLOSE(fp); *stdDev = sqrt(*stdDev/(pixel_count - 1)); for (ii=0; ii<N; ++ii) if (band_data[ii]) FREE(band_data[ii]); *histogram = hist; }
// Main program body. int main (int argc, char *argv[]) { char *leader_file_list, *output_file, file[255]; struct dataset_sum_rec *dssr; struct att_data_rec *atdr; struct VFDRECV *facdr; int currArg = 1; int NUM_ARGS = 2; // process log/quiet/license/etc options handle_common_asf_args(&argc, &argv, ASF_NAME_STRING); asfSplashScreen(argc, argv); if (argc<=1) usage(ASF_NAME_STRING); else if (strmatches(argv[1],"-help","--help",NULL)) print_help(); else if (argc<=2) usage(ASF_NAME_STRING); while (currArg < (argc-NUM_ARGS)) { char *key = argv[currArg++]; if (strmatches(key,"-help","--help",NULL)) { print_help(); // doesn't return } else { --currArg; break; } } if ((argc-currArg) < NUM_ARGS) { printf("Insufficient arguments.\n"); usage(argv[0]); } else if ((argc-currArg) > NUM_ARGS) { printf("Unknown argument: %s\n", argv[currArg]); usage(argv[0]); } leader_file_list = argv[currArg]; output_file = argv[currArg+1]; // Read granule information FILE *fpIn = FOPEN(leader_file_list, "r"); FILE *fpOut = FOPEN(output_file, "w"); fprintf(fpOut, "Leader_file, Yaw, Doppler_range, Doppler_azimuth\n"); dssr = (struct dataset_sum_rec *) MALLOC(sizeof(struct dataset_sum_rec)); atdr = (struct att_data_rec *) MALLOC(sizeof(struct att_data_rec)); facdr = (struct VFDRECV *) MALLOC(sizeof(struct VFDRECV)); double yaw; while (fgets(file, 1024, fpIn)) { file[strlen(file)-1] = '\0'; if (get_dssr(file, dssr) < 0) { asfPrintWarning("Leader file (%s) does not contain data set summary" " record\n", file); continue; } if (get_atdr(file, atdr) < 0) { asfPrintWarning("Leader file (%s) does not contain attitude data record", "\n", file); continue; } if (get_asf_facdr(file, facdr) < 0) { asfPrintWarning("Leader file (%s) does not contain facility related data" " record\n", file); continue; } yaw = facdr->scyaw; if (FLOAT_EQUIVALENT(yaw, 0.0)) yaw = atdr->data->yaw; fprintf(fpOut, "%s, %.4lf, %.3lf, %.3lf\n", file, yaw, dssr->crt_dopcen[0], dssr->alt_dopcen[0]); } FCLOSE(fpIn); FCLOSE(fpOut); FREE(dssr); FREE(atdr); FREE(facdr); asfPrintStatus("Done.\n"); return EXIT_SUCCESS; }
// Determine radiometrically correction amplitude value float get_rad_cal_dn(meta_parameters *meta, int line, int sample, char *bandExt, float inDn, float radCorr) { // Return background value unchanged if (FLOAT_EQUIVALENT(inDn, 0.0)) return 0.0; meta->general->radiometry = r_SIGMA; double incid = meta_incid(meta, line, sample); double sigma = get_cal_dn(meta, incid, sample, inDn, bandExt, FALSE); double calValue, invIncAngle; // Calculate according to the calibration data type if (meta->calibration->type == asf_cal) { // ASF style data (PP and SSP) asf_cal_params *p = meta->calibration->asf; double index = (double)sample*256./(double)(p->sample_count); int base = (int) index; double frac = index - base; double *noise = p->noise; // Determine the noise value double noiseValue = noise[base] + frac*(noise[base+1] - noise[base]); // Convert (amplitude) data number to scaled, noise-removed power //scaledPower = (p->a1*(inDn*inDn-p->a0*noiseValue) + p->a2)*invIncAngle; calValue = sqrt(((sigma * radCorr) - p->a2)/p->a1 + p->a0*noiseValue); } else if (meta->calibration->type == asf_scansar_cal) { // ASF style ScanSar invIncAngle = 1.0; asf_scansar_cal_params *p = meta->calibration->asf_scansar; double look = 25.0; // FIXME: hack to get things compiled double index = (look-16.3)*10.0; double noiseValue; double *noise = p->noise; if (index <= 0) noiseValue = noise[0]; else if (index >= 255) noiseValue = noise[255]; else { // Use linear interpolation on noise array int base = (int)index; double frac = index - base; noiseValue = noise[base] + frac*(noise[base+1] - noise[base]); } // Convert (amplitude) data number to scaled, noise-removed power //scaledPower = (p->a1*(inDn*inDn-p->a0*noiseValue) + p->a2)*invIncAngle; calValue = sqrt(((sigma * radCorr) - p->a2)/p->a1 + p->a0*noiseValue); } else if (meta->calibration->type == esa_cal) { // ESA style ERS and JERS data esa_cal_params *p = meta->calibration->esa; //scaledPower = inDn*inDn/p->k*sin(p->ref_incid*D2R)/sin(incid); calValue = sqrt(sigma * radCorr * p->k*sin(p->ref_incid*D2R)*sin(incid)); } else if (meta->calibration->type == rsat_cal) { // CDPF style Radarsat data invIncAngle = 1/tan(incid); rsat_cal_params *p = meta->calibration->rsat; double a2; if (meta->calibration->rsat->focus) a2 = p->lut[0]; else if (sample < (p->samp_inc*(p->n-1))) { int i_low = sample/p->samp_inc; int i_up = i_low + 1; a2 = p->lut[i_low] + ((p->lut[i_up] - p->lut[i_low])*((sample/p->samp_inc) - i_low)); } else a2 = p->lut[p->n-1] + ((p->lut[p->n-1] - p->lut[p->n-2])*((sample/p->samp_inc) - p->n-1)); if (p->slc) //scaledPower = (inDn*inDn)/(a2*a2)*invIncAngle; calValue = sqrt(sigma * radCorr *a2*a2/invIncAngle); else //scaledPower = (inDn*inDn + p->a3)/a2*invIncAngle; calValue = sqrt((sigma * radCorr *a2/invIncAngle) - p->a3); } else if (meta->calibration->type == alos_cal) { // ALOS data alos_cal_params *p = meta->calibration->alos; double cf; if (strstr(bandExt, "HH")) cf = p->cf_hh; else if (strstr(bandExt, "HV")) cf = p->cf_hv; else if (strstr(bandExt, "VH")) cf = p->cf_vh; else if (strstr(bandExt, "VV")) cf = p->cf_vv; //scaledPower = pow(10, cf/10.0)*inDn*inDn*invIncAngle; calValue = sqrt(sigma * radCorr / pow(10, cf/10.0)); } else if (meta->calibration->type == tsx_cal) { invIncAngle = 1/tan(incid); double cf = meta->calibration->tsx->k; //scaledPower = cf*inDn*inDn*invIncAngle; calValue = sqrt(sigma * radCorr / (cf*invIncAngle)); } return calValue; }
void calc_minmax_median(const char *inFile, char *band, double mask, double *min, double *max) { long long ii, jj; float logeps = 10.0 * log10(EPSILON); float median, median0; meta_parameters *meta = meta_read(inFile); int band_number = (!band || strlen(band) == 0 || strcmp(band, "???") == 0) ? 0 : get_band_number(meta->general->bands, meta->general->band_count, band); long sample_count = meta->general->sample_count; long line_count = meta->general->line_count; long pixel_count = sample_count*line_count; long offset = line_count * band_number; float *data_line = MALLOC(sizeof(float) * sample_count); float *data = MALLOC(sizeof(float) * pixel_count); float *data2 = MALLOC(sizeof(float) * pixel_count); // Culling invalid pixels FILE *fp = FOPEN(inFile, "rb"); long valid_pixel_count = 0; asfPrintStatus("\nCalculating min and max using median...\n"); for (ii=0; ii<line_count; ++ii) { get_float_line(fp, meta, ii + offset, data_line); asfPercentMeter(((double)ii/(double)line_count)); for (jj=0; jj<sample_count; ++jj) { if (!FLOAT_EQUIVALENT(data_line[jj], -9999.99) || !FLOAT_EQUIVALENT(data_line[jj], logeps) || ISNAN(mask)) { data[valid_pixel_count] = data_line[jj]; valid_pixel_count++; } } } asfPercentMeter(1.0); FCLOSE(fp); FREE(data_line); // Determine initial min and max *min = INIT_MINMAX; *max = -INIT_MINMAX; float minmin = INIT_MINMAX; float maxmax = -INIT_MINMAX; for (ii=0; ii<valid_pixel_count; ++ii) { data2[ii] = data[ii]; if (data[ii] < minmin) minmin = data[ii]; if (data[ii] > maxmax) maxmax = data[ii]; } median0 = median_value(data, valid_pixel_count); // Determine minimum median = median0; *min = median0; for (ii=0; ii<3; ii++) { pixel_count = -1; for (jj=0; jj<valid_pixel_count; ++jj) if (median0 == minmin) { if (data[jj] <= median) { pixel_count++; data2[pixel_count] = data[jj]; } } else { if (data[jj] < median) { pixel_count++; data2[pixel_count] = data[jj]; } } median = median_value(data2, pixel_count); if (median == minmin) median = *min; *min = median; } // Determine maximum median = median0; *max = median0; for (ii=0; ii<3; ii++) { pixel_count = -1; for (jj=0; jj<valid_pixel_count; ++jj) if (median0 == maxmax) { if (data[jj] >= median) { pixel_count++; data2[pixel_count] = data[jj]; } } else { if (data[jj] > median) { pixel_count++; data2[pixel_count] = data[jj]; } } median = median_value(data2, pixel_count); if (median == maxmax) median = *max; *max = median; } FREE(data); FREE(data2); }