NASA Logo
Ocean Color Science Software

ocssw V2022
get_nc_height.c
Go to the documentation of this file.
1 
7 #include <stdio.h>
8 #include <hdfi.h>
9 #include "nc_gridutils.h"
10 #include "terrain.h"
11 
12 
13 #define PI 3.141592654
14 #define RADEG 57.29577951
15 
16 
18 #define TILE_ROWS 120
19 
20 #define MAXSENZEN 75
21 
22 #define BORDER 0.30
23 
24 #define REMM 6371000.000
25 
26 // only init the dem file once
27 static int firstCall = 1;
28 
29 /* global variables */
30 static grid_info_t* dem_grid = {0};
32 static const char* demNames[] ={"height", "z", "depth", "elevation", "altitude", NULL};
33 static grid_info_t* surfGrid = {0};
35 static const char* surfNames[] = {"water_surface_height", NULL};
36 
40 typedef struct {
41  int number;
42  double NSEW[4];
43  size_t numLat;
44  double startLat;
45  double endLat;
46  double deltaLat;
47  size_t numLon;
48  double startLon;
49  double endLon;
50  double deltaLon;
51  double minval;
52  double maxval;
53  double *height;
54 } tile_struct;
55 
59 static struct {
60  size_t ntiles;
61  size_t ncols[TILE_ROWS];
64 } dem;
65 
70 void print_area(grid_area_t area) {
71  fprintf(stdout, "\tnumLat = %d\n", (int) area.numLat);
72  fprintf(stdout, "\tstartLat = %8.3f\n", area.startLat);
73  fprintf(stdout, "\tendLat = %8.3f\n", area.endLat);
74  fprintf(stdout, "\tnumLon = %d\n", (int) area.numLon);
75  fprintf(stdout, "\tstartLon = %8.3f\n", area.startLon);
76  fprintf(stdout, "\tendLon = %8.3f\n", area.endLon);
77 }
78 
83 void print_tile(tile_struct tile) {
84  fprintf(stdout, "tile # %d\n", tile.number);
85  fprintf(stdout, "\tstartLat = %8.3f\n", tile.startLat);
86  fprintf(stdout, "\tSouth = %8.3f\n", tile.NSEW[1]);
87  fprintf(stdout, "\tNorth = %8.3f\n", tile.NSEW[0]);
88  fprintf(stdout, "\tendLat = %8.3f\n", tile.endLat);
89  fprintf(stdout, "\tnumLat = %d\n", (int) tile.numLat);
90  fprintf(stdout, "\tdeltaLat = %f\n", tile.deltaLat);
91  fprintf(stdout, "\tstartLon = %8.3f\n", tile.startLon);
92  fprintf(stdout, "\tWest = %8.3f\n", tile.NSEW[3]);
93  fprintf(stdout, "\tEast = %8.3f\n", tile.NSEW[2]);
94  fprintf(stdout, "\tendLon = %8.3f\n", tile.endLon);
95  fprintf(stdout, "\tnumLon = %d\n", (int) tile.numLon);
96  fprintf(stdout, "\tdeltaLon = %f\n", tile.deltaLon);
97  fprintf(stdout, "\tvalue (%p) range = {%d,%d}\n",
98  tile.height, (int) tile.minval, (int) tile.maxval);
99 }
100 
105  int itile = 0;
106  int irow, nrows = TILE_ROWS;
107  int icol, ncols, maxcols;
108  double lonborder, latborder = BORDER;
109  double minlat, maxlat, dlat;
110  double minlon, maxlon, dlon;
111  double latfrac;
112 
113  dlat = 180.0 / nrows; // latitude height for each row
114  maxcols = 2 * nrows; // number of columns at equator
115 
116  /* Calculate number of columns in each row */
117  for (irow = 0; irow < nrows; irow++) {
118 
119  // first tile in this row
120  dem.start_tile[irow] = itile;
121 
122  // number of columns varies with latitude
123  latfrac = (double) irow / (nrows - 1);
124  ncols = (int) round(maxcols * sin(PI * latfrac));
125  if (ncols == 0) ncols = 1;
126  dem.ncols[irow] = ncols;
127 
128  // running total number of tiles
129  itile += ncols;
130  }
131  // now itile holds total number of tiles.
132  dem.ntiles = itile;
133 
134  /* Allocate space for tile array */
135  dem.tiles = (tile_struct *) malloc(itile * sizeof (tile_struct));
136  if (dem.tiles == NULL) {
137  fprintf(stderr,
138  "-E- %s:%d: Could not allocate memory for %d tiles\n",
139  __FILE__, __LINE__, itile);
140  exit(1);
141  }
142 
143  /* Calculate extent of each tile */
144 
145  /* for each row */
146  for (irow = 0; irow < nrows; irow++) {
147 
148  // nominal edge latitudes for this row
149  minlat = dlat * irow - 90.0;
150  maxlat = minlat + dlat;
151 
152  // adjust for border
153  minlat -= latborder;
154  if (minlat < -90.0) minlat = -90.0;
155  maxlat += latborder;
156  if (maxlat > 90.0) maxlat = 90.0;
157 
158  // longitude width for each column of this row
159  ncols = dem.ncols[irow];
160  dlon = 360.0 / ncols;
161 
162  // calculate longitude border for this row
163  if (ncols == 1) lonborder = 0; // unless at poles
164  else if (minlat < 0)
165  lonborder = latborder / cos(minlat / RADEG);
166  else lonborder = latborder / cos(maxlat / RADEG);
167 
168  /* for each column */
169  for (icol = 0; icol < ncols; icol++) {
170 
171  // nominal edge longitudes for this column
172  minlon = dlon * icol - 180.0;
173  maxlon = minlon + dlon;
174 
175  // adjust for border
176  minlon -= lonborder;
177  maxlon += lonborder;
178 
179  // store results
180  itile = dem.start_tile[irow] + icol;
181  dem.tiles[itile].NSEW[0] = maxlat;
182  dem.tiles[itile].NSEW[1] = minlat;
183  dem.tiles[itile].NSEW[2] = maxlon;
184  dem.tiles[itile].NSEW[3] = minlon;
185  dem.tiles[itile].number = -1; // flag for tile loaded
186  dem.tiles[itile].height = NULL; // also init values to null
187 
188  } // icol
189  } // irow
190 }
191 
197 int initialize_deminfo(const char* demfile) {
198  int status;
199  dem.ntiles = 0;
200 
201  /* allocate and load primary elevation info */
202  dem_grid = allocate_gridinfo();
203  status = init_gridinfo(demfile, demNames, dem_grid);
204  if (status != NC_NOERR) {
205  free(dem_grid);
206  dem_grid = NULL;
207  fprintf(stderr, "-E- %s line %d: "
208  "Unable to initialize grid for digital elevation \"%s\".\n",
209  __FILE__, __LINE__, demfile);
210  return status;
211  }
212 
213  /* allocate and load secondary elevation info */
214  surfGrid = allocate_gridinfo();
215  status = init_gridinfo(demfile, surfNames, surfGrid);
216  if (status != NC_NOERR) {
217  free(surfGrid);
218  surfGrid = NULL;
219  fprintf(stderr, "-W- %s line %d: "
220  "Could not read secondary grid info from \"%s\"; continuing.\n",
221  __FILE__, __LINE__, demfile);
222  status = NC_NOERR;
223  }
224 
225  /* Initialize tile geometry */
227 
228  return status;
229 }
230 
234 void free_deminfo() {
235  int i;
236  if (dem_grid != NULL) {
237 
238  /* free space allocated for tile values */
239  for (i = 0; i < dem.ntiles; i++)
240  if (dem.tiles[i].height != NULL) {
241  free(dem.tiles[i].height);
242  dem.tiles[i].height = NULL;
243  }
244 
245  /* free space allocated for tile array */
246  free(dem.tiles);
247  dem.tiles = NULL;
248 
249  /* free surfGrid and dem_grid */
250  if (surfGrid != NULL) {
251  free(surfGrid);
252  surfGrid = NULL;
253  }
254  free(dem_grid);
255  dem_grid = NULL;
256  }
257 }
258 
259 void unload_tile(int itile) {
260  tile_struct *tile;
261 
262  tile = &dem.tiles[itile];
263  free(tile->height);
264  tile->height = NULL;
265  tile->number = -1;
266 }
267 
268 void load_tile_cache(int itile) {
269  const int list_size = 30;
270  static int tile_list[30];
271  static int num_in_list = 0;
272 
273  //printf("***** load tile = %d\n", itile);
274 
275  tile_list[num_in_list++] = itile;
276  if(num_in_list == list_size) {
277  unload_tile(tile_list[0]);
278  num_in_list--;
279  for(int i=0; i<num_in_list; i++) {
280  tile_list[i] = tile_list[i+1];
281  }
282  }
283 }
284 
292 int load_tile(float lat, float lon) {
293  int status;
294  double dlat, dlon;
295  int irow, icol, itile;
296  tile_struct *tile;
297  grid_area_t elevArea = {0};
298  grid_area_t surfArea = {0};
299  int i, nvalues;
300  double minlat, minlon, maxlon;
301  double minval, maxval;
302 
303  /* enforce valid coordinate range */
304  status = fix_latlon(&lat, &lon);
305  if (status) return -1;
306 
307  /* get tile number for this lat, lon */
308  dlat = 180.0 / TILE_ROWS; // latitude height for each row
309  irow = (int) floor((lat + 90.) / dlat); // row number
310  // make sure we don't run off the end
311  if (irow == TILE_ROWS)
312  irow -= 1;
313  dlon = 360.0 / dem.ncols[irow]; // longitude width for this row
314  if (lon == 180.0)
315  icol = 0;
316  else
317  icol = (int) floor((lon + 180.) / dlon); // column number
318 
319  if (icol > dem.ncols[irow] - 1) {
320  fprintf(stderr, "\nERROR in load_tile():\n");
321  fprintf(stderr, "\ticol = %d ncols = %d\n",
322  icol, (int) dem.ncols[irow]);
323  return -1;
324  }
325  itile = dem.start_tile[irow] + icol; // tile number
326  tile = &dem.tiles[itile];
327 
328  /* load only if not already in memory */
329  if (tile->number != itile) {
330 
331  load_tile_cache(itile);
332 
333  // read values for tile area
334  status = get_grid_area(dem_grid,
335  tile->NSEW[0], tile->NSEW[1],
336  tile->NSEW[2], tile->NSEW[3],
337  &elevArea);
338  if (status) return -1;
339 
340  if (surfGrid != NULL) {
341  status = get_grid_area(surfGrid,
342  tile->NSEW[0], tile->NSEW[1],
343  tile->NSEW[2], tile->NSEW[3],
344  &surfArea);
345  if (status) return -1;
346  }
347 
348  // adjust boundaries as needed
349  minlat = elevArea.startLat;
350  minlon = elevArea.startLon;
351  maxlon = elevArea.endLon;
352  if (maxlon < tile->NSEW[2]) minlon += 360.0;
353  if (minlon > tile->NSEW[3]) minlon -= 360.0;
354 
355  // fill tile structure
356  tile->number = itile;
357  tile->height = elevArea.values;
358 
359  tile->numLat = elevArea.numLat;
360  tile->startLat = minlat;
361  tile->deltaLat = elevArea.grid->deltaLat;
362  tile->endLat = tile->startLat + tile->numLat * tile->deltaLat;
363  if(irow+1 == TILE_ROWS)
364  tile->endLat = 90.0;
365 
366  tile->numLon = elevArea.numLon;
367  tile->startLon = minlon;
368  tile->deltaLon = elevArea.grid->deltaLon;
369  tile->endLon = tile->startLon + tile->numLon * tile->deltaLon;
370 
371  // step through extracted area(s)
372  nvalues = tile->numLat * tile->numLon;
373  minval = fabs(dem_grid->FillValue);
374  maxval = -1 * minval;
375  for (i = 0; i < nvalues; i++) {
376 
377  // substitute values as appropriate
378  if ((surfGrid != NULL) &&
379  (fabs(surfArea.values[i] - surfGrid->FillValue) > DBL_EPSILON))
380  tile->height[i] = surfArea.values[i];
381 
382  // find range
383  if (tile->height[i] < minval) minval = tile->height[i];
384  if (tile->height[i] > maxval) maxval = tile->height[i];
385  }
386  tile->minval = minval;
387  tile->maxval = maxval;
388  free(surfArea.values);
389  }
390 
391  status = ((tile->startLat > lat) || (lat > tile->endLat) ||
392  (tile->startLon > lon)); //|| (lon > tile->endLon));
393  if (status) {
394  fprintf(stderr, "\nERROR in load_tile():\n");
395  fprintf(stderr, "lat=%7.3f lon=%8.3f\n", lat, lon);
396  fprintf(stderr, "dlat=%f irow=%d dlon=%f icol=%d itile=%d\n",
397  dlat, irow, dlon, icol, itile);
398  fprintf(stderr, "lat diffs: %f %f\n", lat - tile->startLat, tile->endLat - lat);
399  fprintf(stderr, "lon diffs: %f %f\n", lon - tile->startLon, tile->endLon - lon);
400  fprintf(stderr, "elevArea:\n");
401  print_area(elevArea);
402  print_tile(*tile);
403  fprintf(stderr, "\n");
404  //exit(1);
405  }
406 
407  return itile;
408 }
409 
417 int tile_findex(tile_struct tile, float lat, float lon, double *findex) {
418  int status;
419  double normLat, normLon;
420 
421  /* enforce valid coordinate range */
422  findex[0] = findex[1] = -999.0;
423  status = fix_latlon(&lat, &lon);
424  if (status) return status; // flag NaN inputs
425 
426  /* calculate array index from normalized lat/lon */
427  normLat = lat - tile.startLat;
428  normLon = lon - tile.startLon;
429  if (normLon < 0.0) normLon += 360.0; // adjust for dateline
430  if (normLon > 360.0) normLon -= 360.0; // crossing
431  findex[0] = normLat / tile.deltaLat;
432  findex[1] = normLon / tile.deltaLon;
433 
434  /* cap latitude at North pole */
435  if ((findex[0] >= tile.numLat) &&
436  ((tile.endLat + FLT_EPSILON) > 90.0))
437  findex[0] = (double) tile.numLat - FLT_EPSILON;
438 
439  /* longitudes wrap for global tile only */
440  if ((findex[1] >= tile.numLon) &&
441  ((tile.endLon - tile.startLon + FLT_EPSILON) > 360.0))
442  findex[1] -= tile.numLon;
443 
444  /* make sure final index is inside current tile */
445  status = ((0 > findex[0]) || (findex[0] >= tile.numLat) ||
446  (0 > findex[1]) || (findex[1] >= tile.numLon));
447  if (status) {
448  fprintf(stderr, "-E- %s:%d: tile_findex():\n",
449  __FILE__, __LINE__);
450  fprintf(stderr, "input lat = %7.3f lon = %8.3f\n", lat, lon);
451  fprintf(stderr, "norm lat = %7.3f lon = %8.3f\n", normLat, normLon);
452  fprintf(stderr, "output flat = %7.3f flon = %8.3f\n",
453  findex[0], findex[1]);
454  fprintf(stderr, " numLat = %7d Lon = %8d\n",
455  (int) tile.numLat, (int) tile.numLon);
456  print_tile(tile);
457  fprintf(stderr, "\n");
458  }
459  return status;
460 }
461 
469 int tile_index(tile_struct tile, float lat, float lon, size_t *index) {
470  int status;
471  double findex[2];
472 
473  /* calculate float array index */
474  status = tile_findex(tile, lat, lon, findex);
475 
476  /* make sure max value gives valid index */
477  if (findex[0] > tile.numLat - 1) findex[0] -= FLT_EPSILON;
478  if (findex[1] > tile.numLon - 1) findex[1] -= FLT_EPSILON;
479 
480  /* truncate to integer */
481  index[0] = (int) findex[0];
482  index[1] = (int) findex[1];
483 
484  return status; // inherited from tile_findex
485 }
486 
494 int get_tilevalue(tile_struct tile, float lat, float lon, double *value) {
495  int status = 1;
496  size_t index[2];
497  if (tile.height != NULL) {
498  status = tile_index(tile, lat, lon, index);
499  if (!status)
500  *value = tile.height[index[0] * tile.numLon + index[1]];
501  }
502  return status;
503 }
504 
512 int interp_tilevalue(tile_struct tile, float lat, float lon, double *result) {
513  int status = 1;
514  size_t index[2];
515  double findex[2];
516  size_t x0, x1, y0, y1;
517  size_t nx;
518  double x, y;
519 
520  if (tile.height == NULL) return 1;
521 
522  /* find integer array index for current point */
523  status = tile_index(tile, lat, lon, index);
524  if (status) return status;
525 
526  /* find adjacent points */
527  y0 = index[0];
528  y1 = y0 + 1;
529  x0 = index[1];
530  x1 = x0 + 1;
531 
532  /* cap latitude at North pole */
533  if (y1 == tile.numLat)
534  y1 = tile.numLat - 1;
535 
536  /* longitudes wrap for global tile only */
537  if ((x1 == tile.numLon) &&
538  ((tile.endLon - tile.startLon + FLT_EPSILON) > 360.0))
539  x1 = 0;
540 
541  /* make sure all four points within tile bounds */
542  status = ((y1 > tile.numLat - 1) || (x1 > tile.numLon - 1));
543  if (status) {
544  tile_findex(tile, lat, lon, findex);
545  fprintf(stderr, "-E- %s:%d: interp_tilevalue():\n",
546  __FILE__, __LINE__);
547  fprintf(stderr, " lat = %7.3f lon = %8.3f\n", lat, lon);
548  fprintf(stderr, " flat = %7.3f flon = %8.3f\n",
549  findex[0], findex[1]);
550  fprintf(stderr, " ilat = %7d ilon = %8d\n", (int) y0, (int) x0);
551  fprintf(stderr, "numLat = %7d Lon = %8d\n",
552  (int) tile.numLat, (int) tile.numLon);
553  print_tile(tile);
554  fprintf(stderr, "\n");
555  return status;
556  }
557 
558  /* find float array index */
559  /* shift to unit coordinate system */
560  tile_findex(tile, lat, lon, findex);
561  y = findex[0] - index[0];
562  x = findex[1] - index[1];
563 
564  /* calculate interpolated value */
565  nx = tile.numLon;
566  *result
567  = tile.height[y0 * nx + x0] * (1 - x)*(1 - y) // x=0, y=0
568  + tile.height[y0 * nx + x1] * x * (1 - y) // x=1, y=0
569  + tile.height[y1 * nx + x0] * (1 - x) * y // x=0, y=1
570  + tile.height[y1 * nx + x1] * x * y; // x=1, y=1
571 
572  return status;
573 }
574 
583 int get_nc_height(const char* demfile, float *xlon, float *xlat,
584  float *senz, float *sena,
585  float *height) {
586  int status;
587  static double ddist;
588  double step = 0.5;
589  double tszmin = 0.01;
590  double tansnz, sinsna, cossna, coslat;
591  double lat, lon, dlat, dlon;
592  double dd, dist;
593  double dem_hgt, dem_old, los_hgt, los_old;
594  int stepnum, maxsteps;
595  int itile;
596  tile_struct tile;
597 
598  if (firstCall) {
599  /* Initialize DEM info */
600  if (initialize_deminfo(demfile)) return 1;
601  firstCall = 0;
602  }
603 
604  /* Set step size in meters */
605  if(ddist == 0.0)
606  ddist = step * REMM * 180.0 / (dem_grid->numLat * RADEG);
607 
608  /* Skip if close to limb */
609  if (*senz > MAXSENZEN) {
610  return 0;
611  }
612 
613  /* Load tile for this lat,lon */
614  itile = load_tile(*xlat, *xlon);
615  if ((itile < 0) || (itile > dem.ntiles - 1)) {
616  fprintf(stderr, "\nERROR from load_tile():");
617  fprintf(stderr, "\txlat=%8.3f xlon=%8.3f itile=%d\n",
618  *xlat, *xlon, itile);
619  return 1;
620  }
621  tile = dem.tiles[itile];
622 
623  /* Default for sea-level tile */
624  if (((int) tile.minval == 0) &&
625  ((int) tile.maxval == 0)) {
626  *height = 0.0f;
627  return 0;
628  }
629 
630  /* Pre-compute trig functions */
631  tansnz = tan(*senz / RADEG);
632  sinsna = sin(*sena / RADEG);
633  cossna = cos(*sena / RADEG);
634  coslat = cos(*xlat / RADEG);
635  dlat = cossna * RADEG / REMM;
636  dlon = sinsna * RADEG / (REMM * coslat);
637  if(fabs(dlon) > 360.0)
638  dlon = 0.0;
639 
640  /* If flat tile */
641  if ((tile.maxval - tile.minval) < 1.0) {
642  *height = (float) tile.maxval;
643  dist = *height * tansnz * REMM / (REMM + *height);
644  }
645  /* Check for sensor zenith close to zero */
646  else if (tansnz < tszmin) {
647  status = interp_tilevalue(tile, *xlat, *xlon, &dem_hgt);
648  *height = (float) dem_hgt;
649  dist = *height * tansnz;
650  }
651  /* Else step downward along line-of-sight */
652  else {
653 
654  /* Determine maximum number of steps above ellipsoid */
655  maxsteps = tile.maxval * tansnz / ddist + 2;
656 
657  /* Initialize search parameters */
658  dem_hgt = 0.0;
659  los_hgt = 0.0;
660  stepnum = maxsteps;
661 
662  /* Step downward along line-of-sight until terrain intersection */
663  do {
664  los_old = los_hgt;
665  dem_old = dem_hgt;
666  dist = stepnum * ddist;
667 
668  /* Interpolated height from DEM */
669  lat = *xlat + dist * dlat;
670  lon = *xlon + dist * dlon;
671  status = interp_tilevalue(tile, lat, lon, &dem_hgt);
672  if (status) {
673  fprintf(stderr, "-E- %s:%d: get_nc_height():\n",
674  __FILE__, __LINE__);
675  fprintf(stderr, "\titer = %6d\n", maxsteps - stepnum);
676  return status;
677  }
678 
679  /* LOS height with correction for Earth curvature effect */
680  los_hgt = dist
681  * (dist * tansnz / 2.0 + REMM)
682  / (REMM * tansnz - dist);
683  stepnum--;
684  } while (los_hgt > dem_hgt);
685 
686  /* Interpolate to find final distance along line of sight */
687  dd = (dem_hgt - los_hgt) / (dem_hgt - los_hgt + los_old - dem_old);
688  dist += dd * ddist;
689  }
690 
691  /* Compute adjustments to lon, lat, solar zenith and azimuth */
692  /* (need to look at corrections for polar regions) */
693  *xlat += (float) dist * dlat;
694  *xlon += (float) dist * dlon;
695  *senz -= (float) dist * RADEG / REMM;
696  status = interp_tilevalue(tile, *xlat, *xlon, &dem_hgt);
697  *height = (float) dem_hgt;
698 
699  /* Check for longitude transition over date line */
700  if (*xlon > 180.f) {
701  *xlon -= 360.f;
702  }
703  if (*xlon < -180.f) {
704  *xlon += 360.f;
705  }
706 
707  // if lat goes over the pole and back down
708  if(*xlat < -90.0) {
709  *xlat = -180.0 - *xlat;
710  if(*xlon > 0.0)
711  *xlon -= 180.0;
712  else
713  *xlon += 180.0;
714  } else if(*xlat > 90.0) {
715  *xlat = 180.0 - *xlat;
716  if(*xlon > 0.0)
717  *xlon -= 180.0;
718  else
719  *xlon += 180.0;
720  }
721 
722  return status;
723 }
724 
725 
732 int interp_nc_height(const char* demfile, float *xlon, float *xlat, float *height) {
733  int status;
734  double dem_hgt;
735  int itile;
736  tile_struct tile;
737  if (firstCall) {
738  /* Initialize DEM info */
739  if (initialize_deminfo(demfile)) return 1;
740  firstCall = 0;
741  }
742  /* Load tile for this lat,lon */
743  itile = load_tile(*xlat, *xlon);
744  if ((itile < 0) || (itile > dem.ntiles - 1)) {
745  fprintf(stderr, "\nERROR from load_tile():");
746  fprintf(stderr, "\txlat=%8.3f xlon=%8.3f itile=%d\n",
747  *xlat, *xlon, itile);
748  return 1;
749  }
750  tile = dem.tiles[itile];
751  status = interp_tilevalue(tile, *xlat, *xlon, &dem_hgt);
752  *height = (float) dem_hgt;
753  return status;
754 }
double * height
Definition: get_nc_height.c:46
double startLat
Definition: get_nc_height.c:37
an array had not been initialized Several spelling and grammar corrections were which is read from the appropriate MCF the above metadata values were hard coded A problem calculating the average background DN for SWIR bands when the moon is in the space view port was corrected The new algorithm used to calculate the average background DN for all reflective bands when the moon is in the space view port is now the same as the algorithm employed by the thermal bands For non SWIR changes in the averages are typically less than Also for non SWIR the black body DNs remain a backup in case the SV DNs are not available For SWIR the changes in computed averages were larger because the old which used the black body suffered from contamination by the micron leak As a consequence of the if SV DNs are not available for the SWIR the EV pixels will not be the granule time is used to identify the appropriate tables within the set given for one LUT the first two or last two tables respectively will be used for the interpolation If there is only one LUT in the set of it will be treated as a constant LUT The manner in which Earth View data is checked for saturation was changed Previously the raw Earth View DNs and Space View DNs were checked against the lookup table values contained in the table dn_sat The change made is to check the raw Earth and Space View DNs to be sure they are less than the maximum saturation value and to check the Space View subtracted Earth View dns against a set of values contained in the new lookup table dn_sat_ev The metadata configuration and ASSOCIATEDINSTRUMENTSHORTNAME from the MOD02HKM product The same metatdata with extensions and were removed from the MOD021KM and MOD02OBC products ASSOCIATEDSENSORSHORTNAME was set to MODIS in all products These changes are reflected in new File Specification which users may consult for exact the pow functions were eliminated in Emissive_Cal and Emissive bands replaced by more efficient code Other calculations throughout the code were also made more efficient Aside from a few round off there was no difference to the product The CPU time decreased by about for a day case and for a night case A minor bug in calculating the uncertainty index for emissive bands was corrected The frame index(0-based) was previously being used the frame number(1-based) should have been used. There were only a few minor changes to the uncertainty index(maximum of 1 digit). 3. Some inefficient arrays(Sigma_RVS_norm_sq) were eliminated and some code lines in Preprocess_L1A_Data were moved into Process_OBCEng_Emiss. There were no changes to the product. Required RAM was reduced by 20 MB. Now
int32 value
Definition: Granule.c:1235
double endLon
Definition: nc_gridutils.h:58
int fix_latlon(float *lat, float *lon)
Definition: nc_gridutils.c:281
int interp_nc_height(float *xlon, float *xlat, float *height)
int status
Definition: l1_czcs_hdf.c:32
grid_info_t * grid
Definition: nc_gridutils.h:52
void unload_tile(int itile)
double minval
Definition: get_nc_height.c:44
#define NULL
Definition: decode_rs.h:63
double startLon
Definition: get_nc_height.c:41
int32 nrows
void print_tile(tile_struct tile)
Definition: get_nc_height.c:76
tile_struct * tiles
Definition: get_nc_height.c:56
grid_info_t * allocate_gridinfo()
Definition: nc_gridutils.c:107
character(len=1000) if
Definition: names.f90:13
double endLon
Definition: get_nc_height.c:42
double * values
Definition: nc_gridutils.h:59
size_t numLon
Definition: get_nc_height.c:40
int tile_findex(tile_struct tile, float lat, float lon, double *findex)
void print_area(grid_area_t area)
Definition: get_nc_height.c:63
double endLat
Definition: get_nc_height.c:38
void load_tile_cache(int itile)
#define PI
Definition: get_nc_height.c:13
double precision function f(R1)
Definition: tmd.lp.f:1454
double deltaLon
Definition: get_nc_height.c:43
int init_gridinfo(const char *filename, const char *varnames[], grid_info_t *grid)
Definition: nc_gridutils.c:132
double NSEW[4]
Definition: get_nc_height.c:35
size_t numLat
Definition: get_nc_height.c:36
#define BORDER
Definition: get_nc_height.c:22
double startLon
Definition: nc_gridutils.h:57
int initialize_deminfo()
int interp_tilevalue(tile_struct tile, float lat, float lon, double *result)
#define REMM
Definition: get_nc_height.c:24
int tile_index(tile_struct tile, float lat, float lon, size_t *index)
void free_deminfo()
struct @125 dem
double endLat
Definition: nc_gridutils.h:55
#define MAXSENZEN
Definition: get_nc_height.c:20
void define_tile_geometry()
Definition: get_nc_height.c:97
size_t start_tile[TILE_ROWS]
Definition: get_nc_height.c:55
double maxval
Definition: get_nc_height.c:45
integer, parameter double
#define RADEG
Definition: get_nc_height.c:14
size_t numLon
Definition: nc_gridutils.h:56
float xlon[LAC_PIXEL_NUM]
Definition: l1a_seawifs.c:93
int get_grid_area(grid_info_t *grid, float north, float south, float east, float west, grid_area_t *area)
Definition: nc_gridutils.c:406
double deltaLat
Definition: get_nc_height.c:39
size_t ncols[TILE_ROWS]
Definition: get_nc_height.c:54
double startLat
Definition: nc_gridutils.h:54
size_t numLat
Definition: nc_gridutils.h:53
int load_tile(float lat, float lon)
#define TILE_ROWS
Definition: get_nc_height.c:18
#define fabs(a)
Definition: misc.h:93
int get_nc_height(float *xlon, float *xlat, float *senz, float *sena, float *height)
size_t ntiles
Definition: get_nc_height.c:53
int get_tilevalue(tile_struct tile, float lat, float lon, double *value)
int i
Definition: decode_rs.h:71