OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
nc_gridutils.c
Go to the documentation of this file.
1 
7 #include "nc_gridutils.h"
8 
9 #define NEW_CACHE_SIZE 240000000
10 #define NEW_CACHE_NELEMS 1001
11 #define NEW_CACHE_PREEMPTION .75
12 /* ------------------------------------------------------------------ */
13 /* Utilities */
14 
21 void handle_nc_error(int status, char *file, int line) {
22  fprintf(stderr, "-E- %s:%d: %s\n",
23  file, line, nc_strerror(status));
24  exit(1);
25 }
26 
27 /* ------------------------------------------------------------------ */
28 /* Variables */
29 
34 var_info_t* allocate_varinfo() {
35  var_info_t* var;
36  var = (var_info_t*) malloc(sizeof (var_info_t));
37  if (var == NULL) {
38  fprintf(stderr,
39  "-E- %s:%d: Could not allocate variable info memory.\n",
40  __FILE__, __LINE__);
41  exit(1);
42  }
43  return var;
44 }
45 
52 var_info_t *load_varinfo(int ncid, int varid) {
53  var_info_t *var = {0};
54  int idim; /* dimension ID index */
55 
56  /* initialize variable structure */
58 
59  /* load variable info */
60  nc_inq_var(ncid, varid, var->name, NULL,
61  &var->ndims, var->dimids, NULL);
62 
63  /* load dimension info */
64  for (idim = 0; idim < var->ndims; idim++)
65  nc_inq_dimlen(ncid,
66  var->dimids[idim],
67  &var->dimlen[idim]);
68 
69  /* read fill value from variable attributes */
70  if (nc_get_att_double(ncid, varid, "_FillValue", &var->FillValue))
71  var->FillValue = BAD_VALUE; // otherwise set to default
72 
73  return var;
74 }
75 
83 int find_varid(int ncid, const char *varnames[], int *varid) {
84  int i;
85  int status; /* error status */
86  i = 0;
87  while (varnames[i] != NULL) {
88  status = nc_inq_varid(ncid, varnames[i], varid);
89  if (status == NC_NOERR) break;
90  i++;
91  }
92  return status;
93 }
94 
95 /* ------------------------------------------------------------------ */
96 /* Grid */
97 
99 static const char* latNames[] = {"y", "lat", "latitude", "Latitude", NULL};
101 static const char* lonNames[] = {"x", "lon", "longitude", "Longitude", NULL};
102 
107 grid_info_t* allocate_gridinfo() {
108  grid_info_t* grid = {0};
109  // allocate
110  grid = (grid_info_t*) malloc(sizeof (grid_info_t));
111  if (grid == NULL) {
112  fprintf(stderr,
113  "-E- %s:%d: Could not allocate grid info memory.\n",
114  __FILE__, __LINE__);
115  exit(1);
116  }
117  // initialize
118  grid->file[0] = '\0';
119  grid->ncid = -1;
120  grid->varid = -1;
121  grid->varname[0] = '\0';
122  return grid;
123 }
124 
132 int init_gridinfo(char *filename, const char *varnames[], grid_info_t *grid) {
133  int status;
134  int ncid;
135  var_info_t *var = {0};
136  int varid;
137  size_t index[2];
138  double first, last;
139  int rangeatt; // =1 if coordinate range read from attribute
140 
141  if (nc_set_chunk_cache(NEW_CACHE_SIZE, NEW_CACHE_NELEMS,
142  NEW_CACHE_PREEMPTION) != NC_NOERR) {
143  fprintf(stderr, "-E- %s line %d: nc_set_chunk_cache (%s) failed.\n",
144  __FILE__, __LINE__, filename);
145  return (1);
146  }
147 
148  // open input file
149  status = nc_open(filename, NC_NOWRITE, &ncid);
150  if (status != NC_NOERR) return status;
151 
152  // initialize pre-allocated grid structure
153  strcpy(grid->file, filename);
154  grid->ncid = ncid;
155 
156  // find desired variable
157  status = find_varid(ncid, varnames, &varid);
158  if (status != NC_NOERR) return status;
159  grid->varid = varid;
160 
161  // check dimensions
162  var = load_varinfo(ncid, varid);
163  if (var->ndims != 2) return 1;
164  grid->numLat = var->dimlen[0];
165  grid->numLon = var->dimlen[1];
166  grid->FillValue = var->FillValue;
167  strcpy(grid->varname, var->name);
168  free(var);
169 
170  /* --- read grid registration type from global attributes --- */
171  status = nc_get_att_int(ncid, NC_GLOBAL, "node_offset", &grid->nodeOffset);
172  if (status != NC_NOERR)
173  grid->nodeOffset = 0; // otherwise assume grid-registered
174 
175  // otherwise assume odd # of cells means grid-registered
176  // ( see http://www.ngdc.noaa.gov/mgg/global/gridregistration.html )
177  // grid->nodeOffset = (grid->numLon % 2 == 0); // 0=grid, 1=cell
178 
179 
180  /* --- read LATITUDE limits from global attributes --- */
181  rangeatt = 1;
182  if (nc_get_att_double(ncid, NC_GLOBAL, "lower_lat", &first) ||
183  nc_get_att_double(ncid, NC_GLOBAL, "upper_lat", &last)) {
184 
185  // otherwise read array values
186  rangeatt = 0;
187  if (find_varid(ncid, latNames, &varid)) {
188  fprintf(stderr, "-E- %s:%d: "
189  "No latitude attributes or variables found in %s.",
190  __FILE__, __LINE__, grid->file);
191  return 1;
192  }
193  // check dimensions
194  var = load_varinfo(ncid, varid);
195  if ((var->ndims != 1) || (var->dimlen[0] != grid->numLat)) {
196  fprintf(stderr, "-E- %s:%d: "
197  "Latitude array %s has wrong dimensions.",
198  __FILE__, __LINE__, var->name);
199  return 1;
200  }
201  // read first and last value of array
202  index[0] = 0;
203  index[1] = var->dimlen[0] - 1;
204  status = nc_get_var1_double(ncid, varid, &index[0], &first);
205  status = nc_get_var1_double(ncid, varid, &index[1], &last);
206  free(var);
207  }
208 
209  /* calculate step size */
210  if (rangeatt && grid->nodeOffset)
211  grid->deltaLat = (last - first) / (double) (grid->numLat);
212  else
213  grid->deltaLat = (last - first) / (double) (grid->numLat - 1);
214 
215  /* extend range to cover outer half-pixels */
216  first -= grid->deltaLat / 2.0;
217  last += grid->deltaLat / 2.0;
218 
219  /* save parameters */
220  grid->startLat = first;
221  grid->validLat[0] = (first < last) ? first : last;
222  grid->validLat[1] = (first < last) ? last : first;
223  grid->globalLat = fabs(last - first) >= 180.0;
224 
225  /* --- read LONGITUDE limits from global attributes --- */
226  rangeatt = 1;
227  if (nc_get_att_double(ncid, NC_GLOBAL, "left_lon", &first) ||
228  nc_get_att_double(ncid, NC_GLOBAL, "right_lon", &last)) {
229 
230  // otherwise read array values
231  rangeatt = 0;
232  if (find_varid(ncid, lonNames, &varid)) {
233  fprintf(stderr, "-E- %s:%d: "
234  "No longitude attributes or variables found in %s.",
235  __FILE__, __LINE__, grid->file);
236  return 1;
237  }
238  // check dimensions
239  var = load_varinfo(ncid, varid);
240  if ((var->ndims != 1) || (var->dimlen[0] != grid->numLon)) {
241  fprintf(stderr, "-E- %s:%d: "
242  "Longitude array %s has wrong dimensions.",
243  __FILE__, __LINE__, var->name);
244  return 1;
245  }
246  // read first and last value of array
247  index[0] = 0;
248  index[1] = var->dimlen[0] - 1;
249  status = nc_get_var1_double(ncid, varid, &index[0], &first);
250  status = nc_get_var1_double(ncid, varid, &index[1], &last);
251  free(var);
252  }
253 
254  /* calculate step size */
255  if (first > last) last += 360.0;
256  if (rangeatt && grid->nodeOffset)
257  grid->deltaLon = (last - first) / (double) (grid->numLon);
258  else
259  grid->deltaLon = (last - first) / (double) (grid->numLon - 1);
260 
261 
262  /* extend range to cover outer half-pixels */
263  first -= grid->deltaLon / 2.0;
264  last += grid->deltaLon / 2.0;
265 
266  /* save parameters */
267  grid->startLon = first;
268  grid->validLon[0] = first;
269  grid->validLon[1] = last;
270  grid->globalLon = (last - first) >= 360.0;
271 
272  return 0;
273 }
274 
281 int fix_latlon(float *lat, float *lon) {
282  int status;
283 
284  /* check for valid input */
285  status = (isnan(*lat) || isnan(*lon));
286  if (status) return status;
287 
288  /* latitude changes direction as you cross the poles. */
289  while (*lat < -90.0) {
290  *lat = -180.0 - *lat;
291  //*lon += 180.0; // and you cross to the opposite longitude
292  }
293  while (*lat > 90.0) {
294  *lat = 180.0 - *lat;
295  //*lon += 180.0;
296  }
297 
298  /* longitude keeps wrapping around the globe. */
299  while (*lon < -180.0) *lon += 360.0;
300  while (*lon > 180.0) *lon -= 360.0;
301 
302  return status;
303 }
304 
312 int latlon_findex(grid_info_t *grid, float lat, float lon, double *findex) {
313  int status; // 0=good, 1=bad
314  double normLat, normLon;
315 
316  /* enforce valid coordinate range */
317  findex[0] = findex[1] = -999.0;
318  status = fix_latlon(&lat, &lon);
319  if (status) return status;
320 
321  /* make sure final lat/lon are in grid range. */
322  status = ((grid->validLat[0] > lat) || (lat > grid->validLat[1]) ||
323  (grid->validLon[0] > lon) || (lon > grid->validLon[1]));
324  if (status)
325  return status;
326 
327  /* calculate array index from normalized lat/lon */
328  normLat = lat - grid->startLat;
329  normLon = lon - grid->startLon;
330  findex[0] = normLat / grid->deltaLat;
331  findex[1] = normLon / grid->deltaLon;
332  return status;
333 }
334 
342 int latlon_index(grid_info_t *grid, float lat, float lon, size_t *index) {
343  int status; // 0=good, 1=bad
344  double findex[2];
345 
346  /* calculate float array index */
347  status = latlon_findex(grid, lat, lon, findex);
348  if (status) return status;
349 
350  /* make sure max value gives valid index */
351  if (lat == grid->validLat[1]) findex[0] -= FLT_EPSILON;
352  if (lon == grid->validLon[1]) findex[1] -= FLT_EPSILON;
353 
354  /* truncate to integer */
355  index[0] = (size_t) findex[0];
356  index[1] = (size_t) findex[1];
357 
358  return status; // inherited from latlon_findex
359 }
360 
368 int get_bylatlon(grid_info_t *grid, float lat, float lon, double *value) {
369  int status = 1;
370  size_t index[2];
371  if (grid != NULL) {
372  *value = grid->FillValue;
373  status = latlon_index(grid, lat, lon, index);
374  if (!status) {
375  status = nc_get_var1_double(grid->ncid,
376  grid->varid,
377  index, value);
378  if (status != NC_NOERR)
379  handle_nc_error(status, __FILE__, __LINE__);
380  // test for fill value
381  status = fabs(*value - grid->FillValue) < DBL_EPSILON;
382  }
383  }
384  return status;
385 }
386 
394 int has_extra_column(grid_info_t *grid) {
395  return ( (grid->validLon[1] - grid->validLon[0])
396  > (360.0 + grid->deltaLon / 2.0));
397 }
398 
406 int get_grid_area(grid_info_t *grid,
407  float north, float south,
408  float east, float west,
409  grid_area_t *area) {
410  int status = 0;
411  size_t SWindex[2], NEindex[2];
412  size_t start[] = {0, 0};
413  size_t count[] = {2, 2};
414  double *values;
415  size_t iy, ix, ny, nx;
416  size_t nxWest, nxEast;
417  double *westvals, *eastvals;
418  double *outrow, *inrow;
419 
420  /* make sure north > south */
421  if (north < south) { // never extract > half the globe
422  float coord = north;
423  north = south;
424  south = coord;
425  }
426 
427  /* pad north & south a little */
428  if (south < (grid->validLat[0] + grid->deltaLat)) south = grid->validLat[0];
429  if (north > (grid->validLat[1] - grid->deltaLat)) north = grid->validLat[1];
430 
431  /* get subset indices */
432  status = latlon_index(grid,
433  south - FLT_EPSILON,
434  west - FLT_EPSILON,
435  SWindex);
436  if (status) return status;
437  status = latlon_index(grid,
438  north + FLT_EPSILON,
439  east + FLT_EPSILON,
440  NEindex);
441  if (status) return status;
442 
443  start[0] = SWindex[0]; // set latitude values
444  ny = count[0] = NEindex[0] - SWindex[0] + 1;
445 
446  /* simplest case: east > west */
447  if (NEindex[1] > SWindex[1]) {
448  nx = NEindex[1] - SWindex[1] + 1;
449  if ((nx == grid->numLon) && (has_extra_column(grid)))
450  nx -= 1; // skip duplicate end column
451 
452  start[1] = SWindex[1];
453  count[1] = nx;
454  values = (double*) malloc(ny * nx * sizeof (double));
455  status = nc_get_vara_double(grid->ncid, grid->varid,
456  start, count, values);
457  if (status != NC_NOERR) handle_nc_error(status, __FILE__, __LINE__);
458  }
459  /* crossing the dateline: west > east */
460  else {
461  nxWest = grid->numLon - SWindex[1];
462  if (has_extra_column(grid))
463  nxWest -= 1; // skip duplicate end column
464  nxEast = NEindex[1] + 1;
465  nx = nxWest + nxEast;
466 
467  /* west side */
468  start[1] = SWindex[1];
469  count[1] = nxWest;
470  westvals = (double*) malloc(ny * nxWest * sizeof (double));
471  status = nc_get_vara_double(grid->ncid, grid->varid,
472  start, count, westvals);
473  if (status != NC_NOERR) handle_nc_error(status, __FILE__, __LINE__);
474 
475  /* east side */
476  start[1] = 0;
477  count[1] = nxEast;
478  eastvals = (double*) malloc(ny * nxEast * sizeof (double));
479  status = nc_get_vara_double(grid->ncid, grid->varid,
480  start, count, eastvals);
481  if (status != NC_NOERR) handle_nc_error(status, __FILE__, __LINE__);
482 
483  /* merge west and east */
484  values = (double*) malloc(ny * nx * sizeof (double));
485  for (iy = 0; iy < ny; iy++) {
486  /* copy west values into first nxWest columns */
487  outrow = values + iy * nx;
488  inrow = westvals + iy * nxWest;
489  for (ix = 0; ix < nxWest; ix++) outrow[ix] = inrow[ix];
490 
491  /* copy east values into last nxEast columns */
492  outrow += nxWest;
493  inrow = eastvals + iy * nxEast;
494  for (ix = 0; ix < nxEast; ix++) outrow[ix] = inrow[ix];
495  }
496  free(westvals);
497  free(eastvals);
498  }
499 
500  /* calculate actual boundaries of extracted area */
501  south = SWindex[0] * grid->deltaLat + grid->startLat;
502  north = south + ny * grid->deltaLat;
503  west = SWindex[1] * grid->deltaLon + grid->startLon;
504  east = west + nx * grid->deltaLon;
505 
506  /* fill output structure */
507  area->grid = grid;
508  area->numLat = ny;
509  area->startLat = south;
510  area->endLat = north;
511  area->numLon = nx;
512  area->startLon = west;
513  area->endLon = east;
514  area->values = values;
515 
516  return status;
517 }
518 
529 int interp_gridvar(grid_info_t *grid, float lat, float lon, double *result) {
530  int status = 1;
531  double findex[2];
532  size_t index[] = {0, 0};
533  size_t x0, x1, y0, y1;
534  double values[4];
535  double x, y;
536 
537  *result = grid->FillValue;
538 
539  /* find integer array index for current point */
540  status = latlon_index(grid, lat, lon, index);
541  if (status) return status;
542  y0 = index[0];
543  x0 = index[1];
544 
545  /* find integer array index for adjacent points */
546  status = latlon_index(grid, lat + grid->deltaLat, lon + grid->deltaLon, index);
547  y1 = (index[0] < grid->numLat) ? index[0] : y0;
548  x1 = (index[1] < grid->numLon) ? index[1] : x0;
549 
550  /* retrieve nearest 4 data points */
551  index[0] = y0;
552  index[1] = x0; // x=0, y=0
553  status = nc_get_var1_double(grid->ncid, grid->varid, index, &values[0]);
554  if (status != NC_NOERR) handle_nc_error(status, __FILE__, __LINE__);
555 
556  index[0] = y0;
557  index[1] = x1; // x=1, y=0
558  status = nc_get_var1_double(grid->ncid, grid->varid, index, &values[1]);
559  if (status != NC_NOERR) handle_nc_error(status, __FILE__, __LINE__);
560 
561  index[0] = y1;
562  index[1] = x0; // x=0, y=1
563  status = nc_get_var1_double(grid->ncid, grid->varid, index, &values[2]);
564  if (status != NC_NOERR) handle_nc_error(status, __FILE__, __LINE__);
565 
566  index[0] = y1;
567  index[1] = x1; // x=1, y=1
568  status = nc_get_var1_double(grid->ncid, grid->varid, index, &values[3]);
569  if (status != NC_NOERR) handle_nc_error(status, __FILE__, __LINE__);
570 
571  /* find float array index */
572  /* shift to unit coordinate system */
573  status = latlon_findex(grid, lat, lon, findex);
574  y = findex[0] - y0;
575  x = findex[1] - x0;
576 
577  /* calculate interpolated value */
578  /* NOTE: need to fix interp_gridvar to not include FillValue in avg! */
579  *result
580  = values[0] * (1 - x)*(1 - y) // x=0, y=0
581  + values[1] * x * (1 - y) // x=1, y=0
582  + values[2] * (1 - x) * y // x=0, y=1
583  + values[3] * x * y; // x=1, y=1
584 
585  return status;
586 }
587 
592 void print_gridinfo(grid_info_t grid) {
593  fprintf(stdout, "file\t= %s\n", grid.file);
594  fprintf(stdout, "ncid\t= %d\n", grid.ncid);
595  fprintf(stdout, "varid\t= %d\n", grid.varid);
596  fprintf(stdout, "varname\t= %s\n", grid.varname);
597  fprintf(stdout, "FillValue\t= %f\n", grid.FillValue);
598  fprintf(stdout, "nodeOffset\t= %d\n", grid.nodeOffset);
599 
600  fprintf(stdout, "numLat\t= %d\n", (int) grid.numLat);
601  fprintf(stdout, "startLat\t= %f\n", grid.startLat);
602  fprintf(stdout, "deltaLat\t= %.12f\n", grid.deltaLat);
603  fprintf(stdout, "validLat\t= [%f,%f]\n", grid.validLat[0], grid.validLat[1]);
604  fprintf(stdout, "globalLat\t= %d\n", grid.globalLat);
605 
606  fprintf(stdout, "numLon\t= %d\n", (int) grid.numLon);
607  fprintf(stdout, "startLon\t= %f\n", grid.startLon);
608  fprintf(stdout, "deltaLon\t= %.12f\n", grid.deltaLon);
609  fprintf(stdout, "validLon\t= [%f,%f]\n", grid.validLon[0], grid.validLon[1]);
610  fprintf(stdout, "globalLon\t= %d\n", grid.globalLon);
611 }
int find_varid(int ncid, const char *varnames[], int *varid)
Definition: nc_gridutils.c:83
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
var_info_t * allocate_varinfo()
Definition: nc_gridutils.c:34
double endLon
Definition: nc_gridutils.h:58
int fix_latlon(float *lat, float *lon)
Definition: nc_gridutils.c:281
int status
Definition: l1_czcs_hdf.c:32
grid_info_t * grid
Definition: nc_gridutils.h:52
#define NULL
Definition: decode_rs.h:63
#define NEW_CACHE_SIZE
Definition: nc_gridutils.c:9
#define NEW_CACHE_NELEMS
Definition: nc_gridutils.c:10
int interp_gridvar(grid_info_t *grid, float lat, float lon, double *result)
Definition: nc_gridutils.c:529
float * lat
char name[NC_MAX_NAME+1]
Definition: nc4utils.h:57
grid_info_t * allocate_gridinfo()
Definition: nc_gridutils.c:107
var_info_t * load_varinfo(int ncid, int varid)
Definition: nc_gridutils.c:52
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude resolving resolving GSFcd00179 Corrected handling of fill values for[Sensor|Solar][Zenith|Azimuth] resolving MODxl01751 Changed to validate LUT version against a value retrieved from the resolving MODxl02056 Changed to calculate Solar Diffuser angles without adjustment for estimated post launch changes in the MODIS orientation relative to incidentally resolving defects MODxl01766 Also resolves MODxl01947 Changed to ignore fill values in SCI_ABNORM and SCI_STATE rather than treating them as resolving MODxl01780 Changed to use spacecraft ancillary data to recognise when the mirror encoder data is being set by side A or side B and to change calculations accordingly This removes the need for seperate LUTs for Side A and Side B data it makes the new LUTs incompatible with older versions of the and vice versa Also resolves MODxl01685 A more robust GRing algorithm is being which will create a non default GRing anytime there s even a single geolocated pixel in a granule Removed obsolete messages from seed file
Definition: HISTORY.txt:413
int dimids[NC_MAX_VAR_DIMS]
Definition: nc4utils.h:63
double * values
Definition: nc_gridutils.h:59
#define NEW_CACHE_PREEMPTION
Definition: nc_gridutils.c:11
int ndims
Definition: nc4utils.h:59
int latlon_findex(grid_info_t *grid, float lat, float lon, double *findex)
Definition: nc_gridutils.c:312
double startLon
Definition: nc_gridutils.h:57
int latlon_index(grid_info_t *grid, float lat, float lon, size_t *index)
Definition: nc_gridutils.c:342
var_str_nc * var
Definition: nc4utils.h:75
double endLat
Definition: nc_gridutils.h:55
void print_gridinfo(grid_info_t grid)
Definition: nc_gridutils.c:592
char filename[FILENAME_MAX]
Definition: atrem_corl1.h:122
subroutine coord(X, GM, Y)
Definition: coord.f:2
size_t numLon
Definition: nc_gridutils.h:56
int has_extra_column(grid_info_t *grid)
Definition: nc_gridutils.c:394
void handle_nc_error(int status, char *file, int line)
Definition: nc_gridutils.c:21
int get_bylatlon(grid_info_t *grid, float lat, float lon, double *value)
Definition: nc_gridutils.c:368
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
HISTORY txt for MOD_PR01(step one of PGE01) History follows the following convention needed due to new Aqua ReprocessingActual and the expected LUT revision number from PCF Changed to use PGE version for ProductionHistory Added Archive including ProcessingEnvironment Corrected handling of bad to resovle GSFcd02514 Changed to check staged LUT revision number versus the expected LUT revision number from thereby resolving defect report MODxl02056 This change also avoids the memory access violation reported in MODur00039 Changed the way output arrays were initialized with fill values
Definition: HISTORY.txt:162
double startLat
Definition: nc_gridutils.h:54
size_t numLat
Definition: nc_gridutils.h:53
#define fabs(a)
Definition: misc.h:93
float * lon
Definition: dataday.h:40
int i
Definition: decode_rs.h:71
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
int init_gridinfo(char *filename, const char *varnames[], grid_info_t *grid)
Definition: nc_gridutils.c:132
#define BAD_VALUE
Definition: nc_gridutils.h:13
int count
Definition: decode_rs.h:79