示例#1
0
/* 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;
}
示例#2
0
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;
  }
}
示例#3
0
/* 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;
}
示例#4
0
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;
}
示例#5
0
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;
        }
    }
}
示例#6
0
// 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;
}
示例#7
0
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;
}
示例#8
0
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;
}
示例#9
0
/* 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;
}
示例#10
0
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;
}
示例#11
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);
}
示例#12
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;
}
示例#13
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);
}
示例#14
0
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);
}
示例#15
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;
}
示例#16
0
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;
}
示例#17
0
// 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;
}
示例#18
0
// 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;
}
示例#19
0
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);
}