OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
get_nc_height.c
Go to the documentation of this file.
1 
7 #include "l12_proto.h"
8 #include "nc_gridutils.h"
9 
11 #define TILE_ROWS 120
12 
13 #define MAXSENZEN 75
14 
15 #define BORDER 0.30
16 
17 #define REMM 6371000.000
18 
19 // only init the dem file once
20 static int firstCall = 1;
21 
22 /* global variables */
23 static grid_info_t* dem_grid = {0};
25 static const char* demNames[] ={"height", "z", "depth", "elevation", "altitude", NULL};
26 static grid_info_t* surfGrid = {0};
28 static const char* surfNames[] = {"water_surface_height", NULL};
29 
33 typedef struct {
34  int number;
35  double NSEW[4];
36  size_t numLat;
37  double startLat;
38  double endLat;
39  double deltaLat;
40  size_t numLon;
41  double startLon;
42  double endLon;
43  double deltaLon;
44  double minval;
45  double maxval;
46  double *height;
47 } tile_struct;
48 
52 static struct {
53  size_t ntiles;
54  size_t ncols[TILE_ROWS];
57 } dem;
58 
63 void print_area(grid_area_t area) {
64  fprintf(stdout, "\tnumLat = %d\n", (int) area.numLat);
65  fprintf(stdout, "\tstartLat = %8.3f\n", area.startLat);
66  fprintf(stdout, "\tendLat = %8.3f\n", area.endLat);
67  fprintf(stdout, "\tnumLon = %d\n", (int) area.numLon);
68  fprintf(stdout, "\tstartLon = %8.3f\n", area.startLon);
69  fprintf(stdout, "\tendLon = %8.3f\n", area.endLon);
70 }
71 
76 void print_tile(tile_struct tile) {
77  fprintf(stdout, "tile # %d\n", tile.number);
78  fprintf(stdout, "\tstartLat = %8.3f\n", tile.startLat);
79  fprintf(stdout, "\tSouth = %8.3f\n", tile.NSEW[1]);
80  fprintf(stdout, "\tNorth = %8.3f\n", tile.NSEW[0]);
81  fprintf(stdout, "\tendLat = %8.3f\n", tile.endLat);
82  fprintf(stdout, "\tnumLat = %d\n", (int) tile.numLat);
83  fprintf(stdout, "\tdeltaLat = %f\n", tile.deltaLat);
84  fprintf(stdout, "\tstartLon = %8.3f\n", tile.startLon);
85  fprintf(stdout, "\tWest = %8.3f\n", tile.NSEW[3]);
86  fprintf(stdout, "\tEast = %8.3f\n", tile.NSEW[2]);
87  fprintf(stdout, "\tendLon = %8.3f\n", tile.endLon);
88  fprintf(stdout, "\tnumLon = %d\n", (int) tile.numLon);
89  fprintf(stdout, "\tdeltaLon = %f\n", tile.deltaLon);
90  fprintf(stdout, "\tvalue (%p) range = {%d,%d}\n",
91  tile.height, (int) tile.minval, (int) tile.maxval);
92 }
93 
98  int itile = 0;
99  int irow, nrows = TILE_ROWS;
100  int icol, ncols, maxcols;
101  double lonborder, latborder = BORDER;
102  double minlat, maxlat, dlat;
103  double minlon, maxlon, dlon;
104  double latfrac;
105 
106  dlat = 180.0 / nrows; // latitude height for each row
107  maxcols = 2 * nrows; // number of columns at equator
108 
109  /* Calculate number of columns in each row */
110  for (irow = 0; irow < nrows; irow++) {
111 
112  // first tile in this row
113  dem.start_tile[irow] = itile;
114 
115  // number of columns varies with latitude
116  latfrac = (double) irow / (nrows - 1);
117  ncols = (int) round(maxcols * sin(PI * latfrac));
118  if (ncols == 0) ncols = 1;
119  dem.ncols[irow] = ncols;
120 
121  // running total number of tiles
122  itile += ncols;
123  }
124  // now itile holds total number of tiles.
125  dem.ntiles = itile;
126 
127  /* Allocate space for tile array */
128  dem.tiles = (tile_struct *) malloc(itile * sizeof (tile_struct));
129  if (dem.tiles == NULL) {
130  fprintf(stderr,
131  "-E- %s:%d: Could not allocate memory for %d tiles\n",
132  __FILE__, __LINE__, itile);
133  exit(1);
134  }
135 
136  /* Calculate extent of each tile */
137 
138  /* for each row */
139  for (irow = 0; irow < nrows; irow++) {
140 
141  // nominal edge latitudes for this row
142  minlat = dlat * irow - 90.0;
143  maxlat = minlat + dlat;
144 
145  // adjust for border
146  minlat -= latborder;
147  if (minlat < -90.0) minlat = -90.0;
148  maxlat += latborder;
149  if (maxlat > 90.0) maxlat = 90.0;
150 
151  // longitude width for each column of this row
152  ncols = dem.ncols[irow];
153  dlon = 360.0 / ncols;
154 
155  // calculate longitude border for this row
156  if (ncols == 1) lonborder = 0; // unless at poles
157  else if (minlat < 0)
158  lonborder = latborder / cos(minlat / RADEG);
159  else lonborder = latborder / cos(maxlat / RADEG);
160 
161  /* for each column */
162  for (icol = 0; icol < ncols; icol++) {
163 
164  // nominal edge longitudes for this column
165  minlon = dlon * icol - 180.0;
166  maxlon = minlon + dlon;
167 
168  // adjust for border
169  minlon -= lonborder;
170  maxlon += lonborder;
171 
172  // store results
173  itile = dem.start_tile[irow] + icol;
174  dem.tiles[itile].NSEW[0] = maxlat;
175  dem.tiles[itile].NSEW[1] = minlat;
176  dem.tiles[itile].NSEW[2] = maxlon;
177  dem.tiles[itile].NSEW[3] = minlon;
178  dem.tiles[itile].number = -1; // flag for tile loaded
179  dem.tiles[itile].height = NULL; // also init values to null
180 
181  } // icol
182  } // irow
183 }
184 
191  int status;
192  dem.ntiles = 0;
193 
194  /* allocate and load primary elevation info */
195  dem_grid = allocate_gridinfo();
196  status = init_gridinfo(input->demfile, demNames, dem_grid);
197  if (status != NC_NOERR) {
198  free(dem_grid);
199  dem_grid = NULL;
200  fprintf(stderr, "-E- %s line %d: "
201  "Unable to initialize grid for digital elevation \"%s\".\n",
202  __FILE__, __LINE__, input->demfile);
203  return status;
204  }
205 
206  /* allocate and load secondary elevation info */
207  surfGrid = allocate_gridinfo();
208  status = init_gridinfo(input->demfile, surfNames, surfGrid);
209  if (status != NC_NOERR) {
210  free(surfGrid);
211  surfGrid = NULL;
212  fprintf(stderr, "-W- %s line %d: "
213  "Could not read secondary grid info from \"%s\"; continuing.\n",
214  __FILE__, __LINE__, input->demfile);
215  status = NC_NOERR;
216  }
217 
218  /* Initialize tile geometry */
220 
221  return status;
222 }
223 
227 void free_deminfo() {
228  int i;
229  if (dem_grid != NULL) {
230 
231  /* free space allocated for tile values */
232  for (i = 0; i < dem.ntiles; i++)
233  if (dem.tiles[i].height != NULL) {
234  free(dem.tiles[i].height);
235  dem.tiles[i].height = NULL;
236  }
237 
238  /* free space allocated for tile array */
239  free(dem.tiles);
240  dem.tiles = NULL;
241 
242  /* free surfGrid and dem_grid */
243  if (surfGrid != NULL) {
244  free(surfGrid);
245  surfGrid = NULL;
246  }
247  free(dem_grid);
248  dem_grid = NULL;
249  }
250 }
251 
252 void unload_tile(int itile) {
253  tile_struct *tile;
254 
255  tile = &dem.tiles[itile];
256  free(tile->height);
257  tile->height = NULL;
258  tile->number = -1;
259 }
260 
261 void load_tile_cache(int itile) {
262  const int list_size = 30;
263  static int tile_list[30];
264  static int num_in_list = 0;
265 
266  //printf("***** load tile = %d\n", itile);
267 
268  tile_list[num_in_list++] = itile;
269  if(num_in_list == list_size) {
270  unload_tile(tile_list[0]);
271  num_in_list--;
272  for(int i=0; i<num_in_list; i++) {
273  tile_list[i] = tile_list[i+1];
274  }
275  }
276 }
277 
285 int load_tile(float lat, float lon) {
286  int status;
287  double dlat, dlon;
288  int irow, icol, itile;
289  tile_struct *tile;
290  grid_area_t elevArea = {0};
291  grid_area_t surfArea = {0};
292  int i, nvalues;
293  double minlat, minlon, maxlon;
294  double minval, maxval;
295 
296  /* enforce valid coordinate range */
297  status = fix_latlon(&lat, &lon);
298  if (status) return -1;
299 
300  /* get tile number for this lat, lon */
301  dlat = 180.0 / TILE_ROWS; // latitude height for each row
302  irow = (int) floor((lat + 90.) / dlat); // row number
303  // make sure we don't run off the end
304  if (irow == TILE_ROWS)
305  irow -= 1;
306  dlon = 360.0 / dem.ncols[irow]; // longitude width for this row
307  if (lon == 180.0)
308  icol = 0;
309  else
310  icol = (int) floor((lon + 180.) / dlon); // column number
311 
312  if (icol > dem.ncols[irow] - 1) {
313  fprintf(stderr, "\nERROR in load_tile():\n");
314  fprintf(stderr, "\ticol = %d ncols = %d\n",
315  icol, (int) dem.ncols[irow]);
316  return -1;
317  }
318  itile = dem.start_tile[irow] + icol; // tile number
319  tile = &dem.tiles[itile];
320 
321  /* load only if not already in memory */
322  if (tile->number != itile) {
323 
324  load_tile_cache(itile);
325 
326  // read values for tile area
327  status = get_grid_area(dem_grid,
328  tile->NSEW[0], tile->NSEW[1],
329  tile->NSEW[2], tile->NSEW[3],
330  &elevArea);
331  if (status) return -1;
332 
333  if (surfGrid != NULL) {
334  status = get_grid_area(surfGrid,
335  tile->NSEW[0], tile->NSEW[1],
336  tile->NSEW[2], tile->NSEW[3],
337  &surfArea);
338  if (status) return -1;
339  }
340 
341  // adjust boundaries as needed
342  minlat = elevArea.startLat;
343  minlon = elevArea.startLon;
344  maxlon = elevArea.endLon;
345  if (maxlon < tile->NSEW[2]) minlon += 360.0;
346  if (minlon > tile->NSEW[3]) minlon -= 360.0;
347 
348  // fill tile structure
349  tile->number = itile;
350  tile->height = elevArea.values;
351 
352  tile->numLat = elevArea.numLat;
353  tile->startLat = minlat;
354  tile->deltaLat = elevArea.grid->deltaLat;
355  tile->endLat = tile->startLat + tile->numLat * tile->deltaLat;
356 
357  tile->numLon = elevArea.numLon;
358  tile->startLon = minlon;
359  tile->deltaLon = elevArea.grid->deltaLon;
360  tile->endLon = tile->startLon + tile->numLon * tile->deltaLon;
361 
362  // step through extracted area(s)
363  nvalues = tile->numLat * tile->numLon;
364  minval = fabs(dem_grid->FillValue);
365  maxval = -1 * minval;
366  for (i = 0; i < nvalues; i++) {
367 
368  // substitute values as appropriate
369  if ((surfGrid != NULL) &&
370  (fabs(surfArea.values[i] - surfGrid->FillValue) > DBL_EPSILON))
371  tile->height[i] = surfArea.values[i];
372 
373  // find range
374  if (tile->height[i] < minval) minval = tile->height[i];
375  if (tile->height[i] > maxval) maxval = tile->height[i];
376  }
377  tile->minval = minval;
378  tile->maxval = maxval;
379  free(surfArea.values);
380  }
381 
382  status = ((tile->startLat > lat) || (lat > tile->endLat) ||
383  (tile->startLon > lon)); //|| (lon > tile->endLon));
384  if (status) {
385  fprintf(stderr, "\nERROR in load_tile():\n");
386  fprintf(stderr, "lat=%7.3f lon=%8.3f\n", lat, lon);
387  fprintf(stderr, "dlat=%f irow=%d dlon=%f icol=%d itile=%d\n",
388  dlat, irow, dlon, icol, itile);
389  fprintf(stderr, "lat diffs: %f %f\n", lat - tile->startLat, tile->endLat - lat);
390  fprintf(stderr, "lon diffs: %f %f\n", lon - tile->startLon, tile->endLon - lon);
391  fprintf(stderr, "elevArea:\n");
392  print_area(elevArea);
393  print_tile(*tile);
394  fprintf(stderr, "\n");
395  //exit(1);
396  }
397 
398  return itile;
399 }
400 
408 int tile_findex(tile_struct tile, float lat, float lon, double *findex) {
409  int status;
410  double normLat, normLon;
411 
412  /* enforce valid coordinate range */
413  findex[0] = findex[1] = -999.0;
414  status = fix_latlon(&lat, &lon);
415  if (status) return status; // flag NaN inputs
416 
417  /* calculate array index from normalized lat/lon */
418  normLat = lat - tile.startLat;
419  normLon = lon - tile.startLon;
420  if (normLon < 0.0) normLon += 360.0; // adjust for dateline
421  if (normLon > 360.0) normLon -= 360.0; // crossing
422  findex[0] = normLat / tile.deltaLat;
423  findex[1] = normLon / tile.deltaLon;
424 
425  /* cap latitude at North pole */
426  if ((findex[0] >= tile.numLat) &&
427  ((tile.endLat + FLT_EPSILON) > 90.0))
428  findex[0] = (float) tile.numLat - FLT_EPSILON;
429 
430  /* longitudes wrap for global tile only */
431  if ((findex[1] >= tile.numLon) &&
432  ((tile.endLon - tile.startLon + FLT_EPSILON) > 360.0))
433  findex[1] -= tile.numLon;
434 
435  /* make sure final index is inside current tile */
436  status = ((0 > findex[0]) || (findex[0] >= tile.numLat) ||
437  (0 > findex[1]) || (findex[1] >= tile.numLon));
438  if (status) {
439  fprintf(stderr, "-E- %s:%d: tile_findex():\n",
440  __FILE__, __LINE__);
441  fprintf(stderr, "input lat = %7.3f lon = %8.3f\n", lat, lon);
442  fprintf(stderr, "norm lat = %7.3f lon = %8.3f\n", normLat, normLon);
443  fprintf(stderr, "output flat = %7.3f flon = %8.3f\n",
444  findex[0], findex[1]);
445  fprintf(stderr, " numLat = %7d Lon = %8d\n",
446  (int) tile.numLat, (int) tile.numLon);
447  print_tile(tile);
448  fprintf(stderr, "\n");
449  }
450  return status;
451 }
452 
460 int tile_index(tile_struct tile, float lat, float lon, size_t *index) {
461  int status;
462  double findex[2];
463 
464  /* calculate float array index */
465  status = tile_findex(tile, lat, lon, findex);
466 
467  /* make sure max value gives valid index */
468  if (findex[0] > tile.numLat - 1) findex[0] -= FLT_EPSILON;
469  if (findex[1] > tile.numLon - 1) findex[1] -= FLT_EPSILON;
470 
471  /* truncate to integer */
472  index[0] = (int) findex[0];
473  index[1] = (int) findex[1];
474 
475  return status; // inherited from tile_findex
476 }
477 
485 int get_tilevalue(tile_struct tile, float lat, float lon, double *value) {
486  int status = 1;
487  size_t index[2];
488  if (tile.height != NULL) {
489  status = tile_index(tile, lat, lon, index);
490  if (!status)
491  *value = tile.height[index[0] * tile.numLon + index[1]];
492  }
493  return status;
494 }
495 
503 int interp_tilevalue(tile_struct tile, float lat, float lon, double *result) {
504  int status = 1;
505  size_t index[2];
506  double findex[2];
507  size_t x0, x1, y0, y1;
508  size_t nx;
509  double x, y;
510 
511  if (tile.height == NULL) return 1;
512 
513  /* find integer array index for current point */
514  status = tile_index(tile, lat, lon, index);
515  if (status) return status;
516 
517  /* find adjacent points */
518  y0 = index[0];
519  y1 = y0 + 1;
520  x0 = index[1];
521  x1 = x0 + 1;
522 
523  /* cap latitude at North pole */
524  if (y1 == tile.numLat)
525  y1 = tile.numLat - 1;
526 
527  /* longitudes wrap for global tile only */
528  if ((x1 == tile.numLon) &&
529  ((tile.endLon - tile.startLon + FLT_EPSILON) > 360.0))
530  x1 = 0;
531 
532  /* make sure all four points within tile bounds */
533  status = ((y1 > tile.numLat - 1) || (x1 > tile.numLon - 1));
534  if (status) {
535  tile_findex(tile, lat, lon, findex);
536  fprintf(stderr, "-E- %s:%d: interp_tilevalue():\n",
537  __FILE__, __LINE__);
538  fprintf(stderr, " lat = %7.3f lon = %8.3f\n", lat, lon);
539  fprintf(stderr, " flat = %7.3f flon = %8.3f\n",
540  findex[0], findex[1]);
541  fprintf(stderr, " ilat = %7d ilon = %8d\n", (int) y0, (int) x0);
542  fprintf(stderr, "numLat = %7d Lon = %8d\n",
543  (int) tile.numLat, (int) tile.numLon);
544  print_tile(tile);
545  fprintf(stderr, "\n");
546  return status;
547  }
548 
549  /* find float array index */
550  /* shift to unit coordinate system */
551  tile_findex(tile, lat, lon, findex);
552  y = findex[0] - index[0];
553  x = findex[1] - index[1];
554 
555  /* calculate interpolated value */
556  nx = tile.numLon;
557  *result
558  = tile.height[y0 * nx + x0] * (1 - x)*(1 - y) // x=0, y=0
559  + tile.height[y0 * nx + x1] * x * (1 - y) // x=1, y=0
560  + tile.height[y1 * nx + x0] * (1 - x) * y // x=0, y=1
561  + tile.height[y1 * nx + x1] * x * y; // x=1, y=1
562 
563  return status;
564 }
565 
574 int get_nc_height(float *xlon, float *xlat,
575  float *senz, float *sena,
576  float *height) {
577  int status;
578  static double ddist;
579  double step = 0.5;
580  double tszmin = 0.01;
581  double tansnz, sinsna, cossna, coslat;
582  double lat, lon, dlat, dlon;
583  double dd, dist;
584  double dem_hgt, dem_old, los_hgt, los_old;
585  int stepnum, maxsteps;
586  int itile;
587  tile_struct tile;
588 
589  if (firstCall) {
590  /* Initialize DEM info */
591  if (initialize_deminfo()) return 1;
592  firstCall = 0;
593  }
594 
595  /* Set step size in meters */
596  if(ddist == 0.0)
597  ddist = step * REMM * 180.0 / (dem_grid->numLat * RADEG);
598 
599  /* Skip if close to limb */
600  if (*senz > MAXSENZEN) {
601  return 0;
602  }
603 
604  /* Load tile for this lat,lon */
605  itile = load_tile(*xlat, *xlon);
606  if ((itile < 0) || (itile > dem.ntiles - 1)) {
607  fprintf(stderr, "\nERROR from load_tile():");
608  fprintf(stderr, "\txlat=%8.3f xlon=%8.3f itile=%d\n",
609  *xlat, *xlon, itile);
610  return 1;
611  }
612  tile = dem.tiles[itile];
613 
614  /* Default for sea-level tile */
615  if (((int) tile.minval == 0) &&
616  ((int) tile.maxval == 0)) {
617  *height = 0.0f;
618  return 0;
619  }
620 
621  /* Pre-compute trig functions */
622  tansnz = tan(*senz / RADEG);
623  sinsna = sin(*sena / RADEG);
624  cossna = cos(*sena / RADEG);
625  coslat = cos(*xlat / RADEG);
626  dlat = cossna * RADEG / REMM;
627  dlon = sinsna * RADEG / (REMM * coslat);
628 
629  /* If flat tile */
630  if ((tile.maxval - tile.minval) < 1.0) {
631  *height = (float) tile.maxval;
632  dist = *height * tansnz * REMM / (REMM + *height);
633  }
634  /* Check for sensor zenith close to zero */
635  else if (tansnz < tszmin) {
636  status = interp_tilevalue(tile, *xlat, *xlon, &dem_hgt);
637  *height = (float) dem_hgt;
638  dist = *height * tansnz;
639  }
640  /* Else step downward along line-of-sight */
641  else {
642 
643  /* Determine maximum number of steps above ellipsoid */
644  maxsteps = tile.maxval * tansnz / ddist + 2;
645 
646  /* Initialize search parameters */
647  dem_hgt = 0.0;
648  los_hgt = 0.0;
649  stepnum = maxsteps;
650 
651  /* Step downward along line-of-sight until terrain intersection */
652  do {
653  los_old = los_hgt;
654  dem_old = dem_hgt;
655  dist = stepnum * ddist;
656 
657  /* Interpolated height from DEM */
658  lat = *xlat + dist * dlat;
659  lon = *xlon + dist * dlon;
660  status = interp_tilevalue(tile, lat, lon, &dem_hgt);
661  if (status) {
662  fprintf(stderr, "-E- %s:%d: get_nc_height():\n",
663  __FILE__, __LINE__);
664  fprintf(stderr, "\titer = %6d\n", maxsteps - stepnum);
665  return status;
666  }
667 
668  /* LOS height with correction for Earth curvature effect */
669  los_hgt = dist
670  * (dist * tansnz / 2.0 + REMM)
671  / (REMM * tansnz - dist);
672  stepnum--;
673  } while (los_hgt > dem_hgt);
674 
675  /* Interpolate to find final distance along line of sight */
676  dd = (dem_hgt - los_hgt) / (dem_hgt - los_hgt + los_old - dem_old);
677  dist += dd * ddist;
678  }
679 
680  /* Compute adjustments to lon, lat, solar zenith and azimuth */
681  /* (need to look at corrections for polar regions) */
682  *xlat += (float) dist * dlat;
683  *xlon += (float) dist * dlon;
684  *senz -= (float) dist * RADEG / REMM;
685  status = interp_tilevalue(tile, *xlat, *xlon, &dem_hgt);
686  *height = (float) dem_hgt;
687 
688  /* Check for longitude transition over date line */
689  if (*xlon > 180.f) {
690  *xlon -= 360.f;
691  }
692  if (*xlon < -180.f) {
693  *xlon += 360.f;
694  }
695 
696  return status;
697 }
698 
705 int lookup_nc_height(float *xlon, float *xlat, float *height) {
706  int status;
707  double dem_hgt;
708  int itile;
709  tile_struct tile;
710  if (firstCall) {
711  /* Initialize DEM info */
712  if (initialize_deminfo()) return 1;
713  firstCall = 0;
714  }
715  /* Load tile for this lat,lon */
716  itile = load_tile(*xlat, *xlon);
717  if ((itile < 0) || (itile > dem.ntiles - 1)) {
718  fprintf(stderr, "\nERROR from load_tile():");
719  fprintf(stderr, "\txlat=%8.3f xlon=%8.3f itile=%d\n",
720  *xlat, *xlon, itile);
721  return 1;
722  }
723  tile = dem.tiles[itile];
724  status = get_tilevalue(tile, *xlat, *xlon, &dem_hgt);
725  *height = (float) dem_hgt;
726  return status;
727 }
728 
735 int interp_nc_height(float *xlon, float *xlat, float *height) {
736  int status;
737  double dem_hgt;
738  int itile;
739  tile_struct tile;
740  if (firstCall) {
741  /* Initialize DEM info */
742  if (initialize_deminfo()) return 1;
743  firstCall = 0;
744  }
745  /* Load tile for this lat,lon */
746  itile = load_tile(*xlat, *xlon);
747  if ((itile < 0) || (itile > dem.ntiles - 1)) {
748  fprintf(stderr, "\nERROR from load_tile():");
749  fprintf(stderr, "\txlat=%8.3f xlon=%8.3f itile=%d\n",
750  *xlat, *xlon, itile);
751  return 1;
752  }
753  tile = dem.tiles[itile];
754  status = interp_tilevalue(tile, *xlat, *xlon, &dem_hgt);
755  *height = (float) dem_hgt;
756  return status;
757 }
double startLat
Definition: get_nc_height.c:37
int initialize_deminfo()
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 NSEW[4]
Definition: get_nc_height.c:35
double endLon
Definition: nc_gridutils.h:58
int fix_latlon(float *lat, float *lon)
Definition: nc_gridutils.c:281
size_t ncols[TILE_ROWS]
Definition: get_nc_height.c:54
double * height
Definition: get_nc_height.c:46
int status
Definition: l1_czcs_hdf.c:32
size_t ntiles
Definition: get_nc_height.c:53
grid_info_t * grid
Definition: nc_gridutils.h:52
#define TILE_ROWS
Definition: get_nc_height.c:11
#define REMM
Definition: get_nc_height.c:17
double minval
Definition: get_nc_height.c:44
#define NULL
Definition: decode_rs.h:63
double startLon
Definition: get_nc_height.c:41
int tile_findex(tile_struct tile, float lat, float lon, double *findex)
int get_tilevalue(tile_struct tile, float lat, float lon, double *value)
struct @126 dem
float * lat
#define MAXSENZEN
Definition: get_nc_height.c:13
size_t start_tile[TILE_ROWS]
Definition: get_nc_height.c:55
grid_info_t * allocate_gridinfo()
Definition: nc_gridutils.c:107
void print_tile(tile_struct tile)
Definition: get_nc_height.c:76
instr * input
character(len=1000) if
Definition: names.f90:13
double endLon
Definition: get_nc_height.c:42
double * values
Definition: nc_gridutils.h:59
#define PI
Definition: l3_get_org.c:6
size_t numLon
Definition: get_nc_height.c:40
void unload_tile(int itile)
double endLat
Definition: get_nc_height.c:38
double precision function f(R1)
Definition: tmd.lp.f:1454
double deltaLon
Definition: get_nc_height.c:43
void free_deminfo()
void print_area(grid_area_t area)
Definition: get_nc_height.c:63
size_t numLat
Definition: get_nc_height.c:36
double startLon
Definition: nc_gridutils.h:57
int load_tile(float lat, float lon)
int32 nrows
int lookup_nc_height(float *xlon, float *xlat, float *height)
double endLat
Definition: nc_gridutils.h:55
double maxval
Definition: get_nc_height.c:45
integer, parameter double
#define BORDER
Definition: get_nc_height.c:15
#define RADEG
Definition: czcs_ctl_pt.c:5
size_t numLon
Definition: nc_gridutils.h:56
int get_nc_height(float *xlon, float *xlat, float *senz, float *sena, float *height)
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
double startLat
Definition: nc_gridutils.h:54
size_t numLat
Definition: nc_gridutils.h:53
#define fabs(a)
Definition: misc.h:93
int interp_nc_height(float *xlon, float *xlat, float *height)
int tile_index(tile_struct tile, float lat, float lon, size_t *index)
float * lon
tile_struct * tiles
Definition: get_nc_height.c:56
void load_tile_cache(int itile)
int interp_tilevalue(tile_struct tile, float lat, float lon, double *result)
int i
Definition: decode_rs.h:71
void define_tile_geometry()
Definition: get_nc_height.c:97
int init_gridinfo(char *filename, const char *varnames[], grid_info_t *grid)
Definition: nc_gridutils.c:132