OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
l2extract_netcdf.c
Go to the documentation of this file.
1 /*
2  * subroutine to extract a netCDF L2 file
3  */
4 
5 #include <netcdf.h>
6 
7 #include <stdio.h>
8 #include <math.h>
9 #include <time.h>
10 #include <string.h>
11 #include <unistd.h>
12 
13 
14 #include <dfutils.h>
15 #include <genutils.h>
16 
17 #include <l12_parms.h>
18 #include <l2_flags.h>
19 
20 #include "l2extract.h"
21 
22 #define MAX_VARIABLES 128
23 
24 #define NCDIE(function){ \
25  int status = function; \
26  switch(status){ \
27  case NC_NOERR: break; \
28  default: printf("NetCDF error: file %s, line %d, %s\n", \
29  __FILE__, __LINE__, nc_strerror(status)); \
30  exit(1); \
31  } \
32 }
33 
34 void copyGlobalAttributes(int ncid_r, int ncid_w) {
35  int numAtts;
36  int i;
37  char name[NC_MAX_NAME + 1];
38 
39  NCDIE(nc_inq_natts(ncid_r, &numAtts));
40  for (i = 0; i < numAtts; i++) {
41  NCDIE(nc_inq_attname(ncid_r, NC_GLOBAL, i, name));
42  NCDIE(nc_copy_att(ncid_r, NC_GLOBAL, name, ncid_w, NC_GLOBAL));
43  }
44 }
45 
46 void copyVariableAttributes(int ncid_r, int varid_r, int ncid_w, int varid_w) {
47  int numAtts;
48  int i;
49  char name[NC_MAX_NAME + 1];
50  // int status;
51 
52  NCDIE(nc_inq_varnatts(ncid_r, varid_r, &numAtts));
53  for (i = 0; i < numAtts; i++) {
54  NCDIE(nc_inq_attname(ncid_r, varid_r, i, name));
55  NCDIE(nc_copy_att(ncid_r, varid_r, name, ncid_w, varid_w));
56  }
57 }
58 
59 int checkIfInProdlist(const char *prodlist, const char *name) {
60  char buf[256];
61 
62  if (prodlist[0] != 0) {
63  strcpy(buf, ",");
64  strcat(buf, name);
65  strcat(buf, ",");
66  char *cptr = strstr(prodlist, buf);
67  if (cptr != NULL) return 1;
68  } else {
69  return 1; // if prodlist is empty always return true
70  }
71 
72  return 0;
73 }
74 
75 
87 void copyVariable(int ncid_r, const char* name, size_t* start, size_t* count,
88  int* dimIds, int ncid_w, void* data) {
89 
90  int status;
91  int varid_r;
92  int varid_w;
93  nc_type xtype;
94  int numDims;
95  int numAtts;
96  size_t chunkSize;
97  size_t chunkNelems;
98  float chunkPreemption;
99 
100  size_t typeSize;
101  int arraySize;
102  int i;
103 
104  static int localDataSize = 0;
105  static char* localData = NULL;
106 
107  int shuffle;
108  int deflate;
109  int deflateLevel;
110 
111  status = nc_inq_varid(ncid_r, name, &varid_r);
112  if (status == NC_NOERR) {
113  NCDIE(nc_inq_var(ncid_r, varid_r, NULL, &xtype, &numDims, NULL, &numAtts));
114  NCDIE(nc_get_var_chunk_cache(ncid_r, varid_r,
115  &chunkSize, &chunkNelems, &chunkPreemption));
116  NCDIE(nc_inq_var_deflate(ncid_r, varid_r,
117  &shuffle, &deflate, &deflateLevel));
118 
119  NCDIE(nc_def_var(ncid_w, name, xtype, numDims, dimIds, &varid_w));
120  NCDIE(nc_set_var_chunk_cache(ncid_w, varid_w,
121  chunkSize, chunkNelems, chunkPreemption));
122  NCDIE(nc_def_var_deflate(ncid_w, varid_w,
123  shuffle, deflate, deflateLevel));
124 
125  copyVariableAttributes(ncid_r, varid_r, ncid_w, varid_w);
126 
127  NCDIE(nc_inq_type(ncid_r, xtype, NULL, &typeSize));
128 
129  if (data == NULL) {
130  // calc array size in num of bytes
131  arraySize = typeSize;
132  for (i = 0; i < numDims; i++) {
133  arraySize *= count[i];
134  }
135 
136  // allocate array
137  if (arraySize > localDataSize) {
138  if (localData)
139  free(localData);
140  localDataSize = arraySize;
141  localData = (char*) malloc(localDataSize);
142  if (localData == NULL) {
143  printf("-E- %s %d: could not allocate data for variable %s\n",
144  __FILE__, __LINE__, name);
145  exit(EXIT_FAILURE);
146  }
147  }
148 
149  NCDIE(nc_get_vara(ncid_r, varid_r, start, count, localData));
150  NCDIE(nc_put_var(ncid_w, varid_w, localData));
151  } else {
152  NCDIE(nc_put_var(ncid_w, varid_w, data));
153  }
154 
155  } // found the variable
156 }
157 
170 int extractNetCDF(const char* infile, const char* outfile, int spix, int epix,
171  int sscan, int escan, const char* prodlist) {
172 
173  int status;
174  idDS ds_id_r, ds_id_w; // data set file ids for reading and writing
175  int rootGroup_r; // netCDF group for read file root
176  int rootGroup_w; // netCDF group for write file root
177  int group_r; // netCDF group for read file
178  int group_w; // netCDF group for write file
179  int subGroup_r; // netCDF sub group for read file
180  int subGroup_w; // netCDF sub group for write file
181  int dim_id;
182  int varid;
183  size_t start[3] = {0, 0, 0};
184  size_t count[3] = {1, 1, 1};
185  int dimIds[3] = {0, 0, 0};
186 
187  size_t numLines_r; // number of line in read file
188  size_t numPixels_r; // number of pixels in read file
189  size_t numPixelControlPoints_r; // number of pixel control points in read file
190  size_t numLines_w; // number of line in write file
191  size_t numPixels_w; // number of pixels in write file
192  size_t numPixelControlPoints_w; // number of pixel control points in read file
193  size_t numTotalBands; // number of total bands (vis + IR) in file
194  size_t numVisibleBands; // number of visible bands in file
195  int s_cntl_pt; // starting pixel control point to write (0 based)
196  int e_cntl_pt; // ending pixel control point to write (0 based)
197  int numLinesDimId; // Number_of_Scan_Lines dimension id
198  int numPixelsDimId; // Number_of_Scan_Lines dimension id
199  int numControlPointsDimId; // Number_of_Scan_Lines dimension id
200  int numTotalBandsDimId; // Number_of_Scan_Lines dimension id
201  int numVisibleBandsDimId; // Number_of_Scan_Lines dimension id
202 
203  int i;
204  int numVariables;
205  int variableIds[MAX_VARIABLES];
206  char name[256];
207 
208  // data sets read in
209  int* cntl_pt_cols;
210  int* cntl_pt_rows;
211  float* latArray;
212  float* lonArray;
213  int* flagArray;
214 
215  ds_id_r = openDS(infile);
216  if (ds_id_r.fid == -1) {
217  printf("could not open \"%s\" for reading.\n", infile);
218  exit(EXIT_FAILURE);
219  }
220  if (ds_id_r.fftype != DS_NCDF) {
221  printf("could not open \"%s\" is not a netCDF4 file.\n", infile);
222  exit(EXIT_FAILURE);
223  }
224  rootGroup_r = ds_id_r.fid;
225 
226  /* Get # of scans and # of pixels */
227  /* ------------------------------ */
228  status = nc_inq_dimid(rootGroup_r, "number_of_lines", &dim_id);
229  if (status != NC_NOERR) {
230  nc_inq_dimid(rootGroup_r, "Number_of_Scan_Lines", &dim_id);
231  }
232  nc_inq_dimlen(rootGroup_r, dim_id, &numLines_r);
233  status = nc_inq_dimid(rootGroup_r, "pixels_per_line", &dim_id);
234  if (status != NC_NOERR) {
235  nc_inq_dimid(rootGroup_r, "Pixels_per_Scan_Line", &dim_id);
236 
237  }
238  nc_inq_dimlen(rootGroup_r, dim_id, &numPixels_r);
239  nc_inq_dimid(rootGroup_r, "pixel_control_points", &dim_id);
240  nc_inq_dimlen(rootGroup_r, dim_id, &numPixelControlPoints_r);
241  status = nc_inq_dimid(rootGroup_r, "number_of_bands", &dim_id);
242  if (status != NC_NOERR) {
243  nc_inq_dimid(rootGroup_r, "total_band_number", &dim_id);
244  }
245  nc_inq_dimlen(rootGroup_r, dim_id, &numTotalBands);
246  status = nc_inq_dimid(rootGroup_r, "number_of_reflective_bands", &dim_id);
247  if (status != NC_NOERR) {
248  nc_inq_dimid(rootGroup_r, "band_number", &dim_id);
249  }
250  nc_inq_dimlen(rootGroup_r, dim_id, &numVisibleBands);
251 
252  char* title = readAttrStr(ds_id_r, "title");
253  if (strstr(title, "Level-2") == NULL) {
254  printf("\"%s\" is not a L2 file.\n", infile);
255  exit(EXIT_FAILURE);
256  }
257 
258  if (sscan < 1) {
259  sscan = 1;
260  }
261  if (sscan >= numLines_r) {
262  printf("sscan needs to be less than number of scans in file.\n");
263  exit(BOUNDS_ERROR);
264  }
265  if (escan < 1 || escan > numLines_r) {
266  escan = numLines_r;
267  }
268  if (escan < sscan) {
269  printf("escan needs to be greater than sscan.\n");
270  exit(BOUNDS_ERROR);
271  }
272  numLines_w = escan - sscan + 1;
273 
274  if (spix < 1) {
275  spix = 1;
276  }
277  if (spix >= numPixels_r) {
278  printf("spix needs to be less than number of pixels in file.\n");
279  exit(BOUNDS_ERROR);
280  }
281  if (epix < 1 || epix > numPixels_r) {
282  epix = numPixels_r;
283  }
284  if (epix < spix) {
285  printf("epix needs to be greater than spix.\n");
286  exit(BOUNDS_ERROR);
287  }
288 
289  // --------------------------------------------------------
290  // make sure all products requested exist in the file
291  // --------------------------------------------------------
292  if(prodlist[0] != 0) {
293  status = nc_inq_ncid(rootGroup_r, "geophysical_data", &group_r);
294  if(status != NC_NOERR) {
295  printf("-E- Could not open \"geophysical_data\" group.\n");
296  exit(EXIT_FAILURE);
297  }
298  char* word;
299  char* tmpProdList = strdup(prodlist);
300  word = strtok(tmpProdList, ",");
301  while(word) {
302  if(word[0] != 0) {
303  status = nc_inq_varid(group_r, word, &varid);
304  if(status != NC_NOERR) {
305  printf("-E- Could not find product \"%s\" in L2 file.\n",
306  word);
307  exit(EXIT_FAILURE);
308  }
309  }
310  word = strtok(NULL, ",");
311  }
312  free(tmpProdList);
313  }
314 
315  // --------------------------------------------------------
316  // set to navigation data group
317  // --------------------------------------------------------
318  nc_inq_ncid(rootGroup_r, "navigation_data", &group_r);
319 
320  // read control points
321  cntl_pt_cols = malloc(numPixelControlPoints_r * sizeof (int));
322  cntl_pt_rows = malloc(numLines_w * sizeof (int));
323  if (cntl_pt_cols == NULL || cntl_pt_rows == NULL) {
324  printf("could not allocate memory for cntl_pt_cols and cntl_pt_rows arrays\n");
325  exit(EXIT_FAILURE);
326  }
327  start[0] = 0;
328  count[0] = numPixelControlPoints_r;
329  NCDIE(nc_inq_varid(group_r, "cntl_pt_cols", &varid));
330  NCDIE(nc_get_vara_int(group_r, varid, start, count, cntl_pt_cols));
331 
332  // find starting pixel control point
333  for (i = 0; i < numPixelControlPoints_r; i++) {
334  if (cntl_pt_cols[i] >= spix) {
335  s_cntl_pt = i;
336  break;
337  }
338  }
339  if (i >= numPixelControlPoints_r) {
340  printf("start pixel control point not found.\n");
341  exit(EXIT_FAILURE);
342  }
343 
344  // adjust spix if not on a control point
345  if (cntl_pt_cols[s_cntl_pt] > spix) {
346  if (s_cntl_pt > 0)
347  s_cntl_pt--;
348  spix = cntl_pt_cols[s_cntl_pt];
349  }
350 
351  // find ending pixel control point
352  e_cntl_pt = numPixelControlPoints_r - 1;
353  for (i = 0; i < numPixelControlPoints_r; i++) {
354  if (cntl_pt_cols[i] > epix) {
355  e_cntl_pt = i - 1;
356  break;
357  }
358  }
359 
360  printf("sscan: %d escan: %d\n", sscan, escan);
361  printf("spixl: %d epixl: %d\n", spix, epix);
362 
363  numPixels_w = epix - spix + 1;
364  numPixelControlPoints_w = e_cntl_pt - s_cntl_pt + 1;
365 
366  // read lat and lon
367  latArray = malloc(numLines_w * numPixelControlPoints_w * sizeof (float));
368  lonArray = malloc(numLines_w * numPixelControlPoints_w * sizeof (float));
369  if (latArray == NULL || lonArray == NULL) {
370  printf("could not allocate memory for lat and lon arrays\n");
371  exit(EXIT_FAILURE);
372  }
373  start[0] = sscan - 1;
374  start[1] = s_cntl_pt;
375  count[0] = numLines_w;
376  count[1] = numPixelControlPoints_w;
377  NCDIE(nc_inq_varid(group_r, "latitude", &varid));
378  NCDIE(nc_get_vara_float(group_r, varid, start, count, latArray));
379  NCDIE(nc_inq_varid(group_r, "longitude", &varid));
380  NCDIE(nc_get_vara_float(group_r, varid, start, count, lonArray));
381 
382  // --------------------------------------------------------
383  // set to geophysical data group
384  // --------------------------------------------------------
385  nc_inq_ncid(rootGroup_r, "geophysical_data", &group_r);
386 
387  flagArray = malloc(numLines_w * numPixels_w * sizeof (int));
388  if (flagArray == NULL) {
389  printf("could not allocate memory for flag array\n");
390  exit(EXIT_FAILURE);
391  }
392  start[0] = sscan - 1;
393  start[1] = spix - 1;
394  count[0] = numLines_w;
395  count[1] = numPixels_w;
396  NCDIE(nc_inq_varid(group_r, "l2_flags", &varid));
397  NCDIE(nc_get_vara_int(group_r, varid, start, count, flagArray));
398 
399 
400  /* Calculate new navigation metadata */
401  /* --------------------------------- */
402 #define GEOBOX_INC 20.0
403 
404  int startDone = 0;
405  int centerDone = 0;
406  int endDone = 0;
407  int ccol = numPixelControlPoints_w / 2;
408  int line, scol, ecol;
409  int lineStart;
410  float last_lat = 0.0;
411  int lastGoodLine = 0;
412  float geobox[4][100];
413  int32_t geobox_cnt = 0;
414  float gring_fval[100];
415  int32_t gring_ival[100];
416 
417  float startCenterLat, startCenterLon;
418  float endCenterLat, endCenterLon;
419  float geoLatMin, geoLatMax;
420  float geoLonMin, geoLonMax;
421 
422  // loop to find beginning info
423  for (line = 0; line < numLines_w; line++) {
424  lineStart = numPixelControlPoints_w*line;
425 
426  // find good start pixel
427  if (!startDone) {
428  for (scol = 0; scol <= ccol; scol++) {
429  // check NAVFAIL flag
430  if (flagArray[line * numPixels_w + cntl_pt_cols[scol] - 1] ^ NAVFAIL) {
431  startDone = 1;
432  geobox[0][geobox_cnt] = lonArray[lineStart + scol];
433  geobox[1][geobox_cnt] = latArray[lineStart + scol];
434  break;
435  } // flag good
436  } // for col
437  } // if not start
438 
439  // find good center pixel
440  if (!centerDone) {
441  // check NAVFAIL flag
442  if (flagArray[line * numPixels_w + cntl_pt_cols[ccol] - 1] ^ NAVFAIL) {
443  centerDone = 1;
444  startCenterLon = lonArray[lineStart + ccol];
445  startCenterLat = latArray[lineStart + ccol];
446  last_lat = startCenterLat;
447  } // flag good
448  } // if not center
449 
450  // find good end pixel
451  if (!endDone) {
452  for (ecol = numPixelControlPoints_w - 1; ecol >= ccol; ecol--) {
453  // check NAVFAIL flag
454  if (flagArray[line * numPixels_w + cntl_pt_cols[ecol] - 1] ^ NAVFAIL) {
455  endDone = 1;
456  geobox[2][geobox_cnt] = lonArray[lineStart + ecol];
457  geobox[3][geobox_cnt] = latArray[lineStart + ecol];
458  break;
459  } // flag good
460  } // for col
461  } // if not start
462 
463  if (startDone && centerDone && endDone)
464  break;
465  }
466 
467  // set the min and max lat lon values
468  geoLonMin = geoLonMax = geobox[0][geobox_cnt];
469  geoLatMin = geoLatMax = geobox[1][geobox_cnt];
470  if (geoLonMin > geobox[2][geobox_cnt])
471  geoLonMin = geobox[2][geobox_cnt];
472  if (geoLatMin > geobox[3][geobox_cnt])
473  geoLatMin = geobox[3][geobox_cnt];
474  if (geoLonMax < geobox[2][geobox_cnt])
475  geoLonMax = geobox[2][geobox_cnt];
476  if (geoLatMax < geobox[3][geobox_cnt])
477  geoLatMax = geobox[3][geobox_cnt];
478  if (geoLonMin > startCenterLon)
479  geoLonMin = startCenterLon;
480  if (geoLonMax < startCenterLon)
481  geoLonMax = startCenterLon;
482 
483  geobox_cnt++;
484 
485  // loop through the rest of the lines
486  for (; line < numLines_w; line++) {
487  lineStart = numPixelControlPoints_w*line;
488 
489  // find first good pixel on line
490  for (scol = 0; scol <= ccol; scol++) {
491  // check NAVFAIL flag
492  if (flagArray[line * numPixels_w + cntl_pt_cols[scol] - 1] ^ NAVFAIL)
493  break;
494  }
495  if (scol == ccol) // could not find start col, so skip this line
496  continue;
497 
498  // find last good pixel
499  for (ecol = numPixelControlPoints_w - 1; ecol >= ccol; ecol--) {
500  // check NAVFAIL flag
501  if (flagArray[line * numPixels_w + cntl_pt_cols[ecol] - 1] ^ NAVFAIL)
502  break;
503  }
504  if (ecol < ccol) // could not find end col, so skip this line
505  continue;
506 
507  lastGoodLine = line;
508 
509  // set min/max for every line
510  if (geoLonMax < lonArray[lineStart + scol])
511  geoLonMax = lonArray[lineStart + scol];
512  if (geoLonMax < lonArray[lineStart + ecol])
513  geoLonMax = lonArray[lineStart + ecol];
514  if (geoLonMin > lonArray[lineStart + scol])
515  geoLonMin = lonArray[lineStart + scol];
516  if (geoLonMin > lonArray[lineStart + ecol])
517  geoLonMin = lonArray[lineStart + ecol];
518 
519  if (geoLatMax < latArray[lineStart + scol])
520  geoLatMax = latArray[lineStart + scol];
521  if (geoLatMax < latArray[lineStart + ecol])
522  geoLatMax = latArray[lineStart + ecol];
523  if (geoLatMin > latArray[lineStart + scol])
524  geoLatMin = latArray[lineStart + scol];
525  if (geoLatMin > latArray[lineStart + ecol])
526  geoLatMin = latArray[lineStart + ecol];
527 
528  // load up geobox
529  if (fabs(last_lat - latArray[lineStart + ccol]) > GEOBOX_INC) {
530  geobox[0][geobox_cnt] = lonArray[lineStart + scol];
531  geobox[1][geobox_cnt] = latArray[lineStart + scol];
532  geobox[2][geobox_cnt] = lonArray[lineStart + ecol];
533  geobox[3][geobox_cnt] = latArray[lineStart + ecol];
534  last_lat = latArray[lineStart + ccol];
535  geobox_cnt++;
536  }
537 
538  } // for lines
539 
540  // make sure we add the last line
541  lineStart = numPixelControlPoints_w*lastGoodLine;
542 
543  // find first good pixel on line
544  for (scol = 0; scol < ccol; scol++) {
545  // check NAVFAIL flag
546  if (flagArray[lastGoodLine * numPixels_w + cntl_pt_cols[scol] - 1] ^ NAVFAIL)
547  break;
548  }
549 
550  // find last good pixel
551  for (ecol = numPixelControlPoints_w - 1; ecol >= ccol; ecol--) {
552  // check NAVFAIL flag
553  if (flagArray[lastGoodLine * numPixels_w + cntl_pt_cols[ecol] - 1] ^ NAVFAIL)
554  break;
555  }
556 
557  endCenterLon = lonArray[lineStart + ccol];
558  endCenterLat = latArray[lineStart + ccol];
559 
560  geobox[0][geobox_cnt] = lonArray[lineStart + scol];
561  geobox[1][geobox_cnt] = latArray[lineStart + scol];
562  geobox[2][geobox_cnt] = lonArray[lineStart + ecol];
563  geobox[3][geobox_cnt] = latArray[lineStart + ecol];
564  geobox_cnt++;
565 
566  /* Create output netCDF file (delete if it exists) */
567  /* ------------------------- */
568  if (access(outfile, F_OK) != -1) {
569  if (unlink(outfile)) {
570  printf("could not delete existing output file %s\n", outfile);
571  exit(EXIT_FAILURE);
572  }
573  }
574  ds_id_w = startDS(outfile, DS_NCDF, DS_WRITE, 5);
575  rootGroup_w = ds_id_w.fid;
576 
577  /* Create dimensions */
578  /* ----------------- */
579  NCDIE(nc_def_dim(rootGroup_w, "number_of_lines", numLines_w, &numLinesDimId));
580  NCDIE(nc_def_dim(rootGroup_w, "pixels_per_line", numPixels_w, &numPixelsDimId));
581  NCDIE(nc_def_dim(rootGroup_w, "pixel_control_points", numPixelControlPoints_w, &numControlPointsDimId));
582  NCDIE(nc_def_dim(rootGroup_w, "number_of_bands", numTotalBands, &numTotalBandsDimId));
583  NCDIE(nc_def_dim(rootGroup_w, "number_of_reflective_bands", numVisibleBands, &numVisibleBandsDimId));
584 
585  // --------------------------------------------------------
586  // set to sensor_band_parameters group
587  // --------------------------------------------------------
588  nc_inq_ncid(rootGroup_r, "sensor_band_parameters", &group_r);
589  nc_def_grp(rootGroup_w, "sensor_band_parameters", &group_w);
590 
591  // copy vcal_gain(visibleBands)
592  start[0] = 0;
593  count[0] = numVisibleBands;
594  dimIds[0] = numVisibleBandsDimId;
595 
596  // loop through all of the variables
597  status = nc_inq_varids(group_r, &numVariables, variableIds);
598  if (status == NC_NOERR) {
599  if (numVariables > MAX_VARIABLES) {
600  printf("-E- %s %d: too many variables in group \"sensor_band_parameters\"\n",
601  __FILE__, __LINE__);
602  exit(EXIT_SUCCESS);
603  }
604  for (i = 0; i < numVariables; i++) {
605  status = nc_inq_varname(group_r, variableIds[i], name);
606  if (strcmp(name, "wavelength") == 0) {
607  count[0] = numTotalBands;
608  dimIds[0] = numTotalBandsDimId;
609  copyVariable(group_r, name, start, count, dimIds, group_w, NULL);
610  count[0] = numVisibleBands;
611  dimIds[0] = numVisibleBandsDimId;
612  } else {
613  copyVariable(group_r, name, start, count, dimIds, group_w, NULL);
614  }
615  }
616  }
617 
618  // --------------------------------------------------------
619  // set to sensor_band_parameters group
620  // --------------------------------------------------------
621  nc_inq_ncid(rootGroup_r, "scan_line_attributes", &group_r);
622  nc_def_grp(rootGroup_w, "scan_line_attributes", &group_w);
623 
624  // set up the copy parameters
625  start[0] = sscan - 1;
626  count[0] = numLines_w;
627  dimIds[0] = numLinesDimId;
628 
629  // loop through all of the variables
630  status = nc_inq_varids(group_r, &numVariables, variableIds);
631  if (status == NC_NOERR) {
632  if (numVariables > MAX_VARIABLES) {
633  printf("-E- %s %d: too many variables in group \"scan_line_attributes\"\n",
634  __FILE__, __LINE__);
635  exit(EXIT_SUCCESS);
636  }
637  for (i = 0; i < numVariables; i++) {
638  status = nc_inq_varname(group_r, variableIds[i], name);
639  copyVariable(group_r, name, start, count, dimIds, group_w, NULL);
640  }
641  }
642 
643  // --------------------------------------------------------
644  // set to geophysical_data group
645  // --------------------------------------------------------
646  nc_inq_ncid(rootGroup_r, "geophysical_data", &group_r);
647  nc_def_grp(rootGroup_w, "geophysical_data", &group_w);
648 
649  // set up the copy parameters
650  start[0] = sscan - 1;
651  start[1] = spix - 1;
652  count[0] = numLines_w;
653  count[1] = numPixels_w;
654  dimIds[0] = numLinesDimId;
655  dimIds[1] = numPixelsDimId;
656 
657  // loop through all of the variables
658  status = nc_inq_varids(group_r, &numVariables, variableIds);
659  if (status == NC_NOERR) {
660  if (numVariables > MAX_VARIABLES) {
661  printf("-E- %s %d: too many variables in group \"scan_line_attributes\"\n",
662  __FILE__, __LINE__);
663  exit(EXIT_SUCCESS);
664  }
665  for (i = 0; i < numVariables; i++) {
666  status = nc_inq_varname(group_r, variableIds[i], name);
667  if (checkIfInProdlist(prodlist, name) == 0) continue;
668  copyVariable(group_r, name, start, count, dimIds, group_w, NULL);
669  }
670  }
671 
672  // --------------------------------------------------------
673  // set to navigation data group
674  // --------------------------------------------------------
675  nc_inq_ncid(rootGroup_r, "navigation_data", &group_r);
676  nc_def_grp(rootGroup_w, "navigation_data", &group_w);
677 
678  // copy longitude(lines, pix_cntl_points)
679  start[0] = sscan - 1;
680  start[1] = s_cntl_pt;
681  count[0] = numLines_w;
682  count[1] = numPixelControlPoints_w;
683  dimIds[0] = numLinesDimId;
684  dimIds[1] = numControlPointsDimId;
685  copyVariable(group_r, "longitude", start, count, dimIds, group_w, lonArray);
686  copyVariable(group_r, "latitude", start, count, dimIds, group_w, latArray);
687 
688  // copy pixel control point cols
689  // modify the cntl_pt_cols to write out
690  for (i = 0; i < numPixelControlPoints_w; i++) {
691  cntl_pt_cols[i] = cntl_pt_cols[s_cntl_pt + i] - cntl_pt_cols[s_cntl_pt] + 1;
692  }
693  start[0] = 0;
694  count[0] = numPixelControlPoints_w;
695  dimIds[0] = numControlPointsDimId;
696  copyVariable(group_r, "cntl_pt_cols", start, count, dimIds, group_w, cntl_pt_cols);
697 
698  // copy pixel control point cols
699  // modify the cntl_pt_rows to write out
700  cntl_pt_rows = malloc(numLines_w * sizeof (int));
701  if (cntl_pt_cols == NULL || cntl_pt_rows == NULL) {
702  printf("could not allocate memory for cntl_pt_cols and cntl_pt_rows arrays\n");
703  exit(EXIT_FAILURE);
704  }
705  for (i = 0; i < numLines_w; i++) {
706  cntl_pt_rows[i] = i + 1;
707  }
708  start[0] = sscan - 1;
709  count[0] = numLines_w;
710  dimIds[0] = numLinesDimId;
711  copyVariable(group_r, "cntl_pt_rows", start, count, dimIds, group_w, cntl_pt_rows);
712  copyVariable(group_r, "tilt", start, count, dimIds, group_w, NULL);
713 
714 
715  // fill up gring
716  int j = 1;
717  gring_fval[0] = geobox[0][0];
718  for (i = 0; i < geobox_cnt; i++) {
719  gring_fval[j++] = geobox[2][i];
720  }
721  for (i = 0; i < geobox_cnt - 1; i++) {
722  gring_fval[j++] = geobox[0][geobox_cnt - 1 - i];
723  }
724  NCDIE(nc_put_att_float(group_w, NC_GLOBAL, "gringpointlongitude", NC_FLOAT, j, gring_fval));
725 
726  j = 1;
727  gring_fval[0] = geobox[1][0];
728  gring_ival[0] = j;
729  for (i = 0; i < geobox_cnt; i++) {
730  gring_ival[j] = j + 1;
731  gring_fval[j++] = geobox[3][i];
732  }
733  for (i = 0; i < geobox_cnt - 1; i++) {
734  gring_ival[j] = j + 1;
735  gring_fval[j++] = geobox[1][geobox_cnt - 1 - i];
736  }
737  NCDIE(nc_put_att_float(group_w, NC_GLOBAL, "gringpointlatitude", NC_FLOAT, j, gring_fval));
738  NCDIE(nc_put_att_int(group_w, NC_GLOBAL, "gringpointsequence", NC_INT, j, gring_ival));
739 
740  // --------------------------------------------------------
741  // set to processing_control group
742  // --------------------------------------------------------
743  nc_inq_ncid(rootGroup_r, "processing_control", &group_r);
744  nc_def_grp(rootGroup_w, "processing_control", &group_w);
745 
746  copyGlobalAttributes(group_r, group_w);
747 
748  // sub group input_parameters
749  nc_inq_ncid(group_r, "input_parameters", &subGroup_r);
750  nc_def_grp(group_w, "input_parameters", &subGroup_w);
751 
752  copyGlobalAttributes(subGroup_r, subGroup_w);
753 
754  // sub group flag_percentages
755  nc_inq_ncid(group_r, "flag_percentages", &subGroup_r);
756  nc_def_grp(group_w, "flag_percentages", &subGroup_w);
757 
758  copyGlobalAttributes(subGroup_r, subGroup_w);
759 
760  // --------------------------------------------------------
761  // copy global attributes
762  // --------------------------------------------------------
763  copyGlobalAttributes(rootGroup_r, rootGroup_w);
764 
765  // write modified global attrbutes
766  NCDIE(nc_put_att_float(rootGroup_w, NC_GLOBAL, "start_center_longitude", NC_FLOAT, 1, &startCenterLon));
767  NCDIE(nc_put_att_float(rootGroup_w, NC_GLOBAL, "start_center_latitude", NC_FLOAT, 1, &startCenterLat));
768  NCDIE(nc_put_att_float(rootGroup_w, NC_GLOBAL, "end_center_longitude", NC_FLOAT, 1, &endCenterLon));
769  NCDIE(nc_put_att_float(rootGroup_w, NC_GLOBAL, "end_center_latitude", NC_FLOAT, 1, &endCenterLat));
770 
771  NCDIE(nc_put_att_float(rootGroup_w, NC_GLOBAL, "northernmost_latitude", NC_FLOAT, 1, &geoLatMax));
772  NCDIE(nc_put_att_float(rootGroup_w, NC_GLOBAL, "southernmost_latitude", NC_FLOAT, 1, &geoLatMin));
773  NCDIE(nc_put_att_float(rootGroup_w, NC_GLOBAL, "easternmost_longitude", NC_FLOAT, 1, &geoLonMax));
774  NCDIE(nc_put_att_float(rootGroup_w, NC_GLOBAL, "westernmost_longitude", NC_FLOAT, 1, &geoLonMin));
775 
776  NCDIE(nc_put_att_float(rootGroup_w, NC_GLOBAL, "geospatial_lat_max", NC_FLOAT, 1, &geoLatMax));
777  NCDIE(nc_put_att_float(rootGroup_w, NC_GLOBAL, "geospatial_lat_min", NC_FLOAT, 1, &geoLatMin));
778  NCDIE(nc_put_att_float(rootGroup_w, NC_GLOBAL, "geospatial_lon_max", NC_FLOAT, 1, &geoLonMax));
779  NCDIE(nc_put_att_float(rootGroup_w, NC_GLOBAL, "geospatial_lon_min", NC_FLOAT, 1, &geoLonMin));
780 
781  nc_close(rootGroup_r);
782  nc_close(rootGroup_w);
783 
784  return EXIT_SUCCESS;
785 }
#define EXIT_SUCCESS
Definition: GEO_basic.h:72
int j
Definition: decode_rs.h:73
int status
Definition: l1_czcs_hdf.c:32
idDS openDS(const char *filename)
Definition: wrapper.c:616
#define NCDIE(function)
#define NULL
Definition: decode_rs.h:63
int extractNetCDF(const char *infile, const char *outfile, int spix, int epix, int sscan, int escan, const char *prodlist)
void copyVariableAttributes(int ncid_r, int varid_r, int ncid_w, int varid_w)
ds_format_t fftype
Definition: dfutils.h:31
int32_t prodlist(int32_t sensorID, int32_t evalmask, const char *inprod, const char *defprod, char outprod[L1_MAXPROD][32])
char * readAttrStr(idDS ds_id, const char *name)
Definition: wrapper.c:102
char * strdup(const char *)
idDS startDS(const char *filename, ds_format_t format, ds_access_t accessmode, int32_t deflate)
Definition: wrapper.c:561
void copyGlobalAttributes(int ncid_r, int ncid_w)
@ DS_NCDF
Definition: dfutils.h:20
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude data
Definition: HISTORY.txt:356
#define BOUNDS_ERROR
int checkIfInProdlist(const char *prodlist, const char *name)
void copyVariable(int ncid_r, const char *name, size_t *start, size_t *count, int *dimIds, int ncid_w, void *data)
@ DS_WRITE
Definition: dfutils.h:25
int32 spix
Definition: l1_czcs_hdf.c:21
#define fabs(a)
Definition: misc.h:93
int32_t fid
Definition: dfutils.h:29
#define GEOBOX_INC
#define MAX_VARIABLES
Definition: dfutils.h:28
int32 epix
Definition: l1_czcs_hdf.c:23
const int deflateLevel
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")
#define NAVFAIL
Definition: l2_flags.h:36
int count
Definition: decode_rs.h:79