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 #include "l2extract_3d_wv.h"
22 
23 #define MAX_VARIABLES 512
24 
25 #define NCDIE(function) \
26  { \
27  int status = function; \
28  switch (status) { \
29  case NC_NOERR: \
30  break; \
31  default: \
32  printf("NetCDF error: file %s, line %d, %s\n", __FILE__, __LINE__, nc_strerror(status)); \
33  exit(1); \
34  } \
35  }
36 
37 void copyGlobalAttributes(int ncid_r, int ncid_w) {
38  int numAtts;
39  int i;
40  char name[NC_MAX_NAME + 1];
41 
42  NCDIE(nc_inq_natts(ncid_r, &numAtts));
43  for (i = 0; i < numAtts; i++) {
44  NCDIE(nc_inq_attname(ncid_r, NC_GLOBAL, i, name));
45  NCDIE(nc_copy_att(ncid_r, NC_GLOBAL, name, ncid_w, NC_GLOBAL));
46  }
47 }
48 
49 void copyVariableAttributes(int ncid_r, int varid_r, int ncid_w, int varid_w) {
50  int numAtts;
51  int i;
52  char name[NC_MAX_NAME + 1];
53  // int status;
54 
55  NCDIE(nc_inq_varnatts(ncid_r, varid_r, &numAtts));
56  for (i = 0; i < numAtts; i++) {
57  NCDIE(nc_inq_attname(ncid_r, varid_r, i, name));
58  NCDIE(nc_copy_att(ncid_r, varid_r, name, ncid_w, varid_w));
59  }
60 }
61 
62 int checkIfInProdlist(const char *prodlist, const char *name) {
63  char buf[256];
64 
65  if (prodlist[0] != 0) {
66  strcpy(buf, ",");
67  strcat(buf, name);
68  strcat(buf, ",");
69  char *cptr = strstr(prodlist, buf);
70  if (cptr != NULL)
71  return 1;
72  } else {
73  return 1; // if prodlist is empty always return true
74  }
75 
76  return 0;
77 }
103 void set_attributes(const char *name, int ncid_r, int ncid_w, int varid_r, int *varid_w, int *dimIds,
104  size_t *chunkSize, int *deflateLevel, int *shuffle, int *numAtts, size_t *chunkNelems,
105  float *chunkPreemption, int *deflate, size_t *typeSize, int *numDims, nc_type *xtype) {
106  // int status;
107  NCDIE(nc_inq_var(ncid_r, varid_r, NULL, xtype, numDims, NULL, numAtts));
108  NCDIE(nc_get_var_chunk_cache(ncid_r, varid_r, chunkSize, chunkNelems, chunkPreemption));
109  NCDIE(nc_inq_var_deflate(ncid_r, varid_r, shuffle, deflate, deflateLevel));
110 
111  NCDIE(nc_def_var(ncid_w, name, *xtype, *numDims, dimIds, varid_w));
112  NCDIE(nc_set_var_chunk_cache(ncid_w, *varid_w, *chunkSize, *chunkNelems, *chunkPreemption));
113  NCDIE(nc_def_var_deflate(ncid_w, *varid_w, *shuffle, *deflate, *deflateLevel));
114 
115  copyVariableAttributes(ncid_r, varid_r, ncid_w, *varid_w);
116 
117  NCDIE(nc_inq_type(ncid_r, *xtype, NULL, typeSize));
118 }
119 
131 void copyVariable(int ncid_r, const char *name, size_t *start, size_t *count, int *dimIds, int ncid_w,
132  void *data) {
133  int status;
134  int varid_r;
135  int varid_w;
136  nc_type xtype;
137  int numDims;
138  int numAtts;
139  size_t chunkSize;
140  size_t chunkNelems;
141  float chunkPreemption;
142 
143  size_t typeSize;
144  int arraySize;
145  int i;
146 
147  static int localDataSize = 0;
148  static char *localData = NULL;
149 
150  int shuffle;
151  int deflate;
152  int deflateLevel;
153 
154  status = nc_inq_varid(ncid_r, name, &varid_r);
155  if (status == NC_NOERR) {
156  set_attributes(name, ncid_r, ncid_w, varid_r, &varid_w, dimIds, &chunkSize, &deflateLevel, &shuffle,
157  &numAtts, &chunkNelems, &chunkPreemption, &deflate, &typeSize, &numDims, &xtype);
158  if (data == NULL) {
159  // calc array size in num of bytes
160  arraySize = typeSize;
161  for (i = 0; i < numDims; i++) {
162  arraySize *= count[i];
163  }
164 
165  // allocate array
166  if (arraySize > localDataSize) {
167  if (localData)
168  free(localData);
169  localDataSize = arraySize;
170  localData = (char *)malloc(localDataSize);
171  if (localData == NULL) {
172  printf("-E- %s %d: could not allocate data for variable %s\n", __FILE__, __LINE__, name);
173  exit(EXIT_FAILURE);
174  }
175  }
176  NCDIE(nc_get_vara(ncid_r, varid_r, start, count, localData));
177  NCDIE(nc_put_var(ncid_w, varid_w, localData));
178  } else {
179  NCDIE(nc_put_var(ncid_w, varid_w, data));
180  }
181  }
182 }
183 
200 void copyVariableSelectedIndexes(int ncid_r, const char *name, size_t *start, size_t *count, int *dimIds,
201  int ncid_w, void *data, int *indexes, int dim_of_indexes) {
202  if (dim_of_indexes < 0) {
203  printf("Supplied dim_of_indexes is negative %d\n", dim_of_indexes);
204  exit(EXIT_FAILURE);
205  }
206  size_t start_local[3] = {0, 0, 0};
207  size_t count_local[3] = {1, 1, 1};
208  size_t start_global[3];
209  size_t count_global[3];
210  for (size_t i = 0; i < 3; i++) {
211  start_global[i] = start[i];
212  count_global[i] = count[i];
213  }
214  int status;
215  int varid_r;
216  int varid_w;
217  nc_type xtype;
218  int numDims;
219  int numAtts;
220  size_t chunkSize;
221  size_t chunkNelems;
222  float chunkPreemption;
223 
224  size_t typeSize;
225  int arraySize;
226  int i;
227 
228  static int localDataSize = 0;
229  static char *localData = NULL;
230 
231  int shuffle;
232  int deflate;
233  int deflateLevel;
234 
235  status = nc_inq_varid(ncid_r, name, &varid_r);
236  if (status == NC_NOERR) {
237  set_attributes(name, ncid_r, ncid_w, varid_r, &varid_w, dimIds, &chunkSize, &deflateLevel, &shuffle,
238  &numAtts, &chunkNelems, &chunkPreemption, &deflate, &typeSize, &numDims, &xtype);
239  if (data == NULL) {
240  // calc array size in num of bytes
241  arraySize = typeSize;
242  if (dim_of_indexes >= numDims) {
243  printf(
244  "Supplied dim_of_indexes execedes the number of dimensions "
245  "%d, %d\n",
246  dim_of_indexes, numDims);
247  exit(EXIT_FAILURE);
248  }
249  for (i = 0; i < numDims; i++) {
250  if (i == dim_of_indexes)
251  continue;
252  arraySize *= count_global[i];
253  count_local[i] = count_global[i];
254  }
255 
256  // allocate array
257  if (arraySize > localDataSize) {
258  if (localData)
259  free(localData);
260  localDataSize = arraySize;
261  localData = (char *)malloc(localDataSize);
262  if (localData == NULL) {
263  printf("-E- %s %d: could not allocate data for variable %s\n", __FILE__, __LINE__, name);
264  exit(EXIT_FAILURE);
265  }
266  }
267  size_t total_size = count_global[dim_of_indexes];
268  count_global[dim_of_indexes] = 1;
269  for (int i_index = 0; i_index < total_size; i_index++) {
270  start_global[dim_of_indexes] = indexes[i_index];
271  start_local[dim_of_indexes] = i_index;
272  NCDIE(nc_get_vara(ncid_r, varid_r, start_global, count_global, localData));
273  NCDIE(nc_put_vara(ncid_w, varid_w, start_local, count_local, localData));
274  }
275  } else {
276  NCDIE(nc_put_var(ncid_w, varid_w, data));
277  }
278  }
279 }
280 
293 int extractNetCDF(const char *infile, const char *outfile, int spix, int epix, int sscan, int escan,
294  const char *prodlist, const char *wavelist) {
295  int status;
296  idDS ds_id_r, ds_id_w; // data set file ids for reading and writing
297  int rootGroup_r; // netCDF group for read file root
298  int rootGroup_w; // netCDF group for write file root
299  int group_r; // netCDF group for read file
300  int group_w; // netCDF group for write file
301  int subGroup_r; // netCDF sub group for read file
302  int subGroup_w; // netCDF sub group for write file
303  int dim_id;
304  int varid;
305  size_t start[3] = {0, 0, 0};
306  size_t count[3] = {1, 1, 1};
307  int dimIds[3] = {0, 0, 0};
308 
309  size_t numLines_r; // number of line in read file
310  size_t numPixels_r; // number of pixels in read file
311  size_t numLines_w; // number of line in write file
312  size_t numPixels_w; // number of pixels in write file
313  size_t numTotalBands; // number of total bands (vis + IR) in file
314  size_t numVisibleBands; // number of visible bands in file
315  size_t numBandsPerPixel; // bands_per_pixel dimension
316  size_t numReflectanceLocationValues; // number_of_reflectance_location_values dimension
317  size_t number_of_wv_3d = 0; // wv 3d
318  int reflectanceLocationValuesFound = 0;
319  int numLinesDimId; // Number_of_Scan_Lines dimension id
320  int numPixelsDimId; // Number_of_Scan_Lines dimension id
321  int numBandsPerPixelDimId; // bands_per_pixel dimension id
322  int numReflectiveLocationValuesDimId; // number_of_reflectance_locations dimension id
323  int numTotalBandsDimId; // Number_of_Scan_Lines dimension id
324  int numVisibleBandsDimId; // Number_of_Scan_Lines dimension id
325  int numwv3dDimId; // netcdf id for number_of_wv_3d dim
326 
327  int i;
328  int numVariables;
329  int variableIds[MAX_VARIABLES];
330  char name[256];
331 
332  // data sets read in
333  float *latArray = NULL;
334  float *lonArray = NULL;
335  int *flagArray = NULL;
336 
337  int *wv_values_to_pass = NULL;
338  int *wv_indexes_to_pass = NULL;
339  int wv_num_to_pass = 0;
340 
341  get_wv3_indexes(infile, wavelist, &wv_values_to_pass, &wv_indexes_to_pass, &wv_num_to_pass, prodlist);
342 
343  ds_id_r = openDS(infile);
344  if (ds_id_r.fid == -1) {
345  printf("could not open \"%s\" for reading.\n", infile);
346  exit(EXIT_FAILURE);
347  }
348  if (ds_id_r.fftype != DS_NCDF) {
349  printf("could not open \"%s\" is not a netCDF4 file.\n", infile);
350  exit(EXIT_FAILURE);
351  }
352  rootGroup_r = ds_id_r.fid;
353 
354  /* Get # of scans and # of pixels */
355  /* ------------------------------ */
356  status = nc_inq_dimid(rootGroup_r, "number_of_lines", &dim_id);
357  if (status != NC_NOERR) {
358  nc_inq_dimid(rootGroup_r, "Number_of_Scan_Lines", &dim_id);
359  }
360  nc_inq_dimlen(rootGroup_r, dim_id, &numLines_r);
361 
362  status = nc_inq_dimid(rootGroup_r, "pixels_per_line", &dim_id);
363  if (status != NC_NOERR) {
364  nc_inq_dimid(rootGroup_r, "Pixels_per_Scan_Line", &dim_id);
365  }
366  nc_inq_dimlen(rootGroup_r, dim_id, &numPixels_r);
367 
368  status = nc_inq_dimid(rootGroup_r, "number_of_bands", &dim_id);
369  if (status != NC_NOERR) {
370  nc_inq_dimid(rootGroup_r, "total_band_number", &dim_id);
371  }
372  nc_inq_dimlen(rootGroup_r, dim_id, &numTotalBands);
373 
374  status = nc_inq_dimid(rootGroup_r, "number_of_reflective_bands", &dim_id);
375  if (status != NC_NOERR) {
376  nc_inq_dimid(rootGroup_r, "band_number", &dim_id);
377  }
378  nc_inq_dimlen(rootGroup_r, dim_id, &numVisibleBands);
379 
380  status = nc_inq_dimid(rootGroup_r, "bands_per_pixel", &dim_id);
381  if (status == NC_NOERR) {
382  nc_inq_dimlen(rootGroup_r, dim_id, &numBandsPerPixel);
383  } else {
384  numBandsPerPixel = numTotalBands;
385  }
386 
387  status = nc_inq_dimid(rootGroup_r, "wavelength_3d", &dim_id);
388  if (status == NC_NOERR)
389  nc_inq_dimlen(rootGroup_r, dim_id, &number_of_wv_3d);
390 
391  status = nc_inq_dimid(rootGroup_r, "number_of_reflectance_location_values", &dim_id);
392  if (status == NC_NOERR) {
393  nc_inq_dimlen(rootGroup_r, dim_id, &numReflectanceLocationValues);
394  reflectanceLocationValuesFound = 1;
395  }
396 
397  char *title = readAttrStr(ds_id_r, "title");
398  if (strstr(title, "Level-2") == NULL) {
399  printf("\"%s\" is not a L2 file.\n", infile);
400  exit(EXIT_FAILURE);
401  }
402  free(title);
403 
404  if (sscan < 1) {
405  sscan = 1;
406  }
407  if (sscan >= numLines_r) {
408  printf("sscan needs to be less than number of scans in file.\n");
409  exit(BOUNDS_ERROR);
410  }
411  if (escan < 1 || escan > numLines_r) {
412  escan = numLines_r;
413  }
414  if (escan < sscan) {
415  printf("escan needs to be greater than sscan.\n");
416  exit(BOUNDS_ERROR);
417  }
418  numLines_w = escan - sscan + 1;
419 
420  if (spix < 1) {
421  spix = 1;
422  }
423  if (spix >= numPixels_r) {
424  printf("spix needs to be less than number of pixels in file.\n");
425  exit(BOUNDS_ERROR);
426  }
427  if (epix < 1 || epix > numPixels_r) {
428  epix = numPixels_r;
429  }
430  if (epix < spix) {
431  printf("epix needs to be greater than spix.\n");
432  exit(BOUNDS_ERROR);
433  }
434 
435  // --------------------------------------------------------
436  // make sure all products requested exist in the file
437  // --------------------------------------------------------
438  if (prodlist[0] != 0) {
439  status = nc_inq_ncid(rootGroup_r, "geophysical_data", &group_r);
440  if (status != NC_NOERR) {
441  printf("-E- Could not open \"geophysical_data\" group.\n");
442  exit(EXIT_FAILURE);
443  }
444  char *word;
445  char *tmpProdList = strdup(prodlist);
446  word = strtok(tmpProdList, ",");
447  while (word) {
448  if (word[0] != 0) {
449  status = nc_inq_varid(group_r, word, &varid);
450  if (status != NC_NOERR) {
451  printf("-E- Could not find product \"%s\" in L2 file.\n", word);
452  exit(EXIT_FAILURE);
453  }
454  }
455  word = strtok(NULL, ",");
456  }
457  free(tmpProdList);
458  }
459 
460  // --------------------------------------------------------
461  // set to navigation data group
462  // --------------------------------------------------------
463  nc_inq_ncid(rootGroup_r, "navigation_data", &group_r);
464 
465  printf("sscan: %d escan: %d\n", sscan, escan);
466  printf("spixl: %d epixl: %d\n", spix, epix);
467 
468  numPixels_w = epix - spix + 1;
469 
470  // read lat and lon
471  latArray = malloc(numLines_w * numPixels_w * sizeof(float));
472  lonArray = malloc(numLines_w * numPixels_w * sizeof(float));
473  if (latArray == NULL || lonArray == NULL) {
474  printf("could not allocate memory for lat and lon arrays\n");
475  exit(EXIT_FAILURE);
476  }
477  start[0] = sscan - 1;
478  start[1] = spix - 1;
479  count[0] = numLines_w;
480  count[1] = numPixels_w;
481  NCDIE(nc_inq_varid(group_r, "latitude", &varid));
482  NCDIE(nc_get_vara_float(group_r, varid, start, count, latArray));
483  NCDIE(nc_inq_varid(group_r, "longitude", &varid));
484  NCDIE(nc_get_vara_float(group_r, varid, start, count, lonArray));
485 
486  // --------------------------------------------------------
487  // set to geophysical data group
488  // --------------------------------------------------------
489  nc_inq_ncid(rootGroup_r, "geophysical_data", &group_r);
490 
491  flagArray = malloc(numLines_w * numPixels_w * sizeof(int));
492  if (flagArray == NULL) {
493  printf("could not allocate memory for flag array\n");
494  exit(EXIT_FAILURE);
495  }
496  start[0] = sscan - 1;
497  start[1] = spix - 1;
498  count[0] = numLines_w;
499  count[1] = numPixels_w;
500  NCDIE(nc_inq_varid(group_r, "l2_flags", &varid));
501  NCDIE(nc_get_vara_int(group_r, varid, start, count, flagArray));
502 
503  /* Calculate new navigation metadata */
504  /* --------------------------------- */
505 #define GEOBOX_INC 20.0
506 
507  int startDone = 0;
508  int centerDone = 0;
509  int endDone = 0;
510  int ccol = numPixels_w / 2;
511  int line, scol, ecol;
512  int lineStart;
513  float last_lat = 0.0;
514  int lastGoodLine = 0;
515  float geobox[4][100];
516  int32_t geobox_cnt = 0;
517  float gring_fval[100];
518  int32_t gring_ival[100];
519 
520  float startCenterLat, startCenterLon;
521  float endCenterLat, endCenterLon;
522  float geoLatMin, geoLatMax;
523  float geoLonMin, geoLonMax;
524 
525  // loop to find beginning info
526  for (line = 0; line < numLines_w; line++) {
527  lineStart = numPixels_w * line;
528 
529  // find good start pixel
530  if (!startDone) {
531  for (scol = 0; scol <= ccol; scol++) {
532  // check NAVFAIL flag
533  if (flagArray[line * numPixels_w + scol] ^ NAVFAIL) {
534  startDone = 1;
535  geobox[0][geobox_cnt] = lonArray[lineStart + scol];
536  geobox[1][geobox_cnt] = latArray[lineStart + scol];
537  break;
538  } // flag good
539  } // for col
540  } // if not start
541 
542  // find good center pixel
543  if (!centerDone) {
544  // check NAVFAIL flag
545  if (flagArray[line * numPixels_w + ccol] ^ NAVFAIL) {
546  centerDone = 1;
547  startCenterLon = lonArray[lineStart + ccol];
548  startCenterLat = latArray[lineStart + ccol];
549  last_lat = startCenterLat;
550  } // flag good
551  } // if not center
552 
553  // find good end pixel
554  if (!endDone) {
555  for (ecol = numPixels_w - 1; ecol >= ccol; ecol--) {
556  // check NAVFAIL flag
557  if (flagArray[line * numPixels_w + ecol] ^ NAVFAIL) {
558  endDone = 1;
559  geobox[2][geobox_cnt] = lonArray[lineStart + ecol];
560  geobox[3][geobox_cnt] = latArray[lineStart + ecol];
561  break;
562  } // flag good
563  } // for col
564  } // if not start
565 
566  if (startDone && centerDone && endDone)
567  break;
568  }
569 
570  // set the min and max lat lon values
571  geoLonMin = geoLonMax = geobox[0][geobox_cnt];
572  geoLatMin = geoLatMax = geobox[1][geobox_cnt];
573  if (geoLonMin > geobox[2][geobox_cnt])
574  geoLonMin = geobox[2][geobox_cnt];
575  if (geoLatMin > geobox[3][geobox_cnt])
576  geoLatMin = geobox[3][geobox_cnt];
577  if (geoLonMax < geobox[2][geobox_cnt])
578  geoLonMax = geobox[2][geobox_cnt];
579  if (geoLatMax < geobox[3][geobox_cnt])
580  geoLatMax = geobox[3][geobox_cnt];
581  if (geoLonMin > startCenterLon)
582  geoLonMin = startCenterLon;
583  if (geoLonMax < startCenterLon)
584  geoLonMax = startCenterLon;
585 
586  geobox_cnt++;
587 
588  // loop through the rest of the lines
589  for (; line < numLines_w; line++) {
590  lineStart = numPixels_w * line;
591 
592  // find first good pixel on line
593  for (scol = 0; scol <= ccol; scol++) {
594  // check NAVFAIL flag
595  if (flagArray[line * numPixels_w + scol] ^ NAVFAIL)
596  break;
597  }
598  if (scol == ccol) // could not find start col, so skip this line
599  continue;
600 
601  // find last good pixel
602  for (ecol = numPixels_w - 1; ecol >= ccol; ecol--) {
603  // check NAVFAIL flag
604  if (flagArray[line * numPixels_w + ecol] ^ NAVFAIL)
605  break;
606  }
607  if (ecol < ccol) // could not find end col, so skip this line
608  continue;
609 
610  lastGoodLine = line;
611 
612  // set min/max for every line
613  if (geoLonMax < lonArray[lineStart + scol])
614  geoLonMax = lonArray[lineStart + scol];
615  if (geoLonMax < lonArray[lineStart + ecol])
616  geoLonMax = lonArray[lineStart + ecol];
617  if (geoLonMin > lonArray[lineStart + scol])
618  geoLonMin = lonArray[lineStart + scol];
619  if (geoLonMin > lonArray[lineStart + ecol])
620  geoLonMin = lonArray[lineStart + ecol];
621 
622  if (geoLatMax < latArray[lineStart + scol])
623  geoLatMax = latArray[lineStart + scol];
624  if (geoLatMax < latArray[lineStart + ecol])
625  geoLatMax = latArray[lineStart + ecol];
626  if (geoLatMin > latArray[lineStart + scol])
627  geoLatMin = latArray[lineStart + scol];
628  if (geoLatMin > latArray[lineStart + ecol])
629  geoLatMin = latArray[lineStart + ecol];
630 
631  // load up geobox
632  if (fabs(last_lat - latArray[lineStart + ccol]) > GEOBOX_INC) {
633  geobox[0][geobox_cnt] = lonArray[lineStart + scol];
634  geobox[1][geobox_cnt] = latArray[lineStart + scol];
635  geobox[2][geobox_cnt] = lonArray[lineStart + ecol];
636  geobox[3][geobox_cnt] = latArray[lineStart + ecol];
637  last_lat = latArray[lineStart + ccol];
638  geobox_cnt++;
639  }
640 
641  } // for lines
642 
643  // make sure we add the last line
644  lineStart = numPixels_w * lastGoodLine;
645 
646  // find first good pixel on line
647  for (scol = 0; scol < ccol; scol++) {
648  // check NAVFAIL flag
649  if (flagArray[lastGoodLine * numPixels_w + scol] ^ NAVFAIL)
650  break;
651  }
652 
653  // find last good pixel
654  for (ecol = numPixels_w - 1; ecol >= ccol; ecol--) {
655  // check NAVFAIL flag
656  if (flagArray[lastGoodLine * numPixels_w + ecol] ^ NAVFAIL)
657  break;
658  }
659 
660  endCenterLon = lonArray[lineStart + ccol];
661  endCenterLat = latArray[lineStart + ccol];
662 
663  geobox[0][geobox_cnt] = lonArray[lineStart + scol];
664  geobox[1][geobox_cnt] = latArray[lineStart + scol];
665  geobox[2][geobox_cnt] = lonArray[lineStart + ecol];
666  geobox[3][geobox_cnt] = latArray[lineStart + ecol];
667  geobox_cnt++;
668 
669  /* Create output netCDF file (delete if it exists) */
670  /* ------------------------- */
671  if (access(outfile, F_OK) != -1) {
672  if (unlink(outfile)) {
673  printf("could not delete existing output file %s\n", outfile);
674  exit(EXIT_FAILURE);
675  }
676  }
677  ds_id_w = startDS(outfile, DS_NCDF, DS_WRITE, 5);
678  rootGroup_w = ds_id_w.fid;
679 
680  /* Create dimensions */
681  /* ----------------- */
682  NCDIE(nc_def_dim(rootGroup_w, "number_of_lines", numLines_w, &numLinesDimId));
683  NCDIE(nc_def_dim(rootGroup_w, "pixels_per_line", numPixels_w, &numPixelsDimId));
684  NCDIE(nc_def_dim(rootGroup_w, "bands_per_pixel", numBandsPerPixel, &numBandsPerPixelDimId));
685  if (number_of_wv_3d > 0) {
686  if (wv_num_to_pass > 0) {
687  number_of_wv_3d = wv_num_to_pass;
688  }
689  NCDIE(nc_def_dim(rootGroup_w, "wavelength_3d", number_of_wv_3d, &numwv3dDimId));
690  }
691 
692  if (reflectanceLocationValuesFound) {
693  NCDIE(nc_def_dim(rootGroup_w, "number_of_reflectance_location_values", numReflectanceLocationValues,
694  &numReflectiveLocationValuesDimId));
695  }
696  NCDIE(nc_def_dim(rootGroup_w, "number_of_bands", numTotalBands, &numTotalBandsDimId));
697  NCDIE(nc_def_dim(rootGroup_w, "number_of_reflective_bands", numVisibleBands, &numVisibleBandsDimId));
698 
699  // --------------------------------------------------------
700  // set to sensor_band_parameters group
701  // --------------------------------------------------------
702  nc_inq_ncid(rootGroup_r, "sensor_band_parameters", &group_r);
703  nc_def_grp(rootGroup_w, "sensor_band_parameters", &group_w);
704 
705  // copy vcal_gain(visibleBands)
706  start[0] = 0;
707  count[0] = numVisibleBands;
708  dimIds[0] = numVisibleBandsDimId;
709 
710  // loop through all of the variables
711  status = nc_inq_varids(group_r, &numVariables, variableIds);
712  if (status == NC_NOERR) {
713  if (numVariables > MAX_VARIABLES) {
714  printf("-E- %s %d: too many variables in group \"sensor_band_parameters\"\n",
715  __FILE__, __LINE__);
716  exit(EXIT_SUCCESS);
717  }
718  for (i = 0; i < numVariables; i++) {
719  status = nc_inq_varname(group_r, variableIds[i], name);
720  if ((strcmp(name, "wavelength") == 0)) {
721  count[0] = numTotalBands;
722  dimIds[0] = numTotalBandsDimId;
723  copyVariable(group_r, name, start, count, dimIds, group_w, NULL);
724  } else {
725  if ((strcmp(name, "wavelength_3d") == 0)) {
726  count[0] = number_of_wv_3d;
727  dimIds[0] = numwv3dDimId;
728  if (wv_num_to_pass > 0) {
729  copyVariableSelectedIndexes(group_r, name, start, count, dimIds, group_w, NULL,
730  wv_indexes_to_pass, 0);
731  continue;
732  }
733  } else {
734  count[0] = numVisibleBands;
735  dimIds[0] = numVisibleBandsDimId;
736  }
737  copyVariable(group_r, name, start, count, dimIds, group_w, NULL);
738  }
739  }
740  }
741 
742  // --------------------------------------------------------
743  // set to sensor_band_parameters group
744  // --------------------------------------------------------
745  nc_inq_ncid(rootGroup_r, "scan_line_attributes", &group_r);
746  nc_def_grp(rootGroup_w, "scan_line_attributes", &group_w);
747 
748  // set up the copy parameters
749  start[0] = sscan - 1;
750  count[0] = numLines_w;
751  dimIds[0] = numLinesDimId;
752 
753  // loop through all of the variables
754  status = nc_inq_varids(group_r, &numVariables, variableIds);
755  if (status == NC_NOERR) {
756  if (numVariables > MAX_VARIABLES) {
757  printf("-E- %s %d: too many variables in group \"scan_line_attributes\"\n",
758  __FILE__, __LINE__);
759  exit(EXIT_SUCCESS);
760  }
761  for (i = 0; i < numVariables; i++) {
762  status = nc_inq_varname(group_r, variableIds[i], name);
763  copyVariable(group_r, name, start, count, dimIds, group_w, NULL);
764  }
765  }
766 
767  // --------------------------------------------------------
768  // set to geophysical_data group
769  // --------------------------------------------------------
770  nc_inq_ncid(rootGroup_r, "geophysical_data", &group_r);
771  nc_def_grp(rootGroup_w, "geophysical_data", &group_w);
772 
773  // set up the copy parameters
774  start[0] = sscan - 1;
775  start[1] = spix - 1;
776  count[0] = numLines_w;
777  count[1] = numPixels_w;
778  dimIds[0] = numLinesDimId;
779  dimIds[1] = numPixelsDimId;
780 
781  // loop through all of the variables
782  status = nc_inq_varids(group_r, &numVariables, variableIds);
783  if (status == NC_NOERR) {
784  if (numVariables > MAX_VARIABLES) {
785  printf("-E- %s %d: too many variables in group \"geophysical_data\"\n",
786  __FILE__, __LINE__);
787  exit(EXIT_SUCCESS);
788  }
789  for (i = 0; i < numVariables; i++) {
790  status = nc_inq_varname(group_r, variableIds[i], name);
791  {
792  int varids_dims[3] = {0, 0, 0};
793  char dim_name[50];
794  nc_inq_vardimid(group_r, variableIds[i], varids_dims);
795  nc_inq_dimname(group_r, varids_dims[2], dim_name);
796  if (strcmp(dim_name, "wavelength_3d") == 0) {
797  dimIds[2] = numwv3dDimId;
798  count[2] = number_of_wv_3d;
799  if (wv_indexes_to_pass > 0) {
800  if (checkIfInProdlist(prodlist, name) == 0)
801  continue;
802  copyVariableSelectedIndexes(group_r, name, start, count, dimIds, group_w, NULL,
803  wv_indexes_to_pass, 2);
804  continue;
805  }
806  } else {
807  dimIds[2] = 0;
808  count[2] = 1;
809  }
810  }
811  if (checkIfInProdlist(prodlist, name) == 0)
812  continue;
813  copyVariable(group_r, name, start, count, dimIds, group_w, NULL);
814  }
815  }
816 
817  // --------------------------------------------------------
818  // set to navigation data group
819  // --------------------------------------------------------
820  nc_inq_ncid(rootGroup_r, "navigation_data", &group_r);
821  nc_def_grp(rootGroup_w, "navigation_data", &group_w);
822 
823  start[0] = sscan - 1;
824  start[1] = spix - 1;
825  count[0] = numLines_w;
826  count[1] = numPixels_w;
827  dimIds[0] = numLinesDimId;
828  dimIds[1] = numPixelsDimId;
829  copyVariable(group_r, "longitude", start, count, dimIds, group_w, lonArray);
830  copyVariable(group_r, "latitude", start, count, dimIds, group_w, latArray);
831 
832  start[0] = sscan - 1;
833  count[0] = numLines_w;
834  dimIds[0] = numLinesDimId;
835  copyVariable(group_r, "tilt", start, count, dimIds, group_w, NULL);
836 
837  // fill up gring
838  int j = 1;
839  gring_fval[0] = geobox[0][0];
840  for (i = 0; i < geobox_cnt; i++) {
841  gring_fval[j++] = geobox[2][i];
842  }
843  for (i = 0; i < geobox_cnt - 1; i++) {
844  gring_fval[j++] = geobox[0][geobox_cnt - 1 - i];
845  }
846  NCDIE(nc_put_att_float(group_w, NC_GLOBAL, "gringpointlongitude", NC_FLOAT, j, gring_fval));
847 
848  j = 1;
849  gring_fval[0] = geobox[1][0];
850  gring_ival[0] = j;
851  for (i = 0; i < geobox_cnt; i++) {
852  gring_ival[j] = j + 1;
853  gring_fval[j++] = geobox[3][i];
854  }
855  for (i = 0; i < geobox_cnt - 1; i++) {
856  gring_ival[j] = j + 1;
857  gring_fval[j++] = geobox[1][geobox_cnt - 1 - i];
858  }
859  NCDIE(nc_put_att_float(group_w, NC_GLOBAL, "gringpointlatitude", NC_FLOAT, j, gring_fval));
860  NCDIE(nc_put_att_int(group_w, NC_GLOBAL, "gringpointsequence", NC_INT, j, gring_ival));
861 
862  // --------------------------------------------------------
863  // set to processing_control group
864  // --------------------------------------------------------
865  nc_inq_ncid(rootGroup_r, "processing_control", &group_r);
866  nc_def_grp(rootGroup_w, "processing_control", &group_w);
867 
868  copyGlobalAttributes(group_r, group_w);
869 
870  // sub group input_parameters
871  nc_inq_ncid(group_r, "input_parameters", &subGroup_r);
872  nc_def_grp(group_w, "input_parameters", &subGroup_w);
873 
874  copyGlobalAttributes(subGroup_r, subGroup_w);
875 
876  // sub group flag_percentages
877  nc_inq_ncid(group_r, "flag_percentages", &subGroup_r);
878  nc_def_grp(group_w, "flag_percentages", &subGroup_w);
879 
880  copyGlobalAttributes(subGroup_r, subGroup_w);
881 
882  // --------------------------------------------------------
883  // copy global attributes
884  // --------------------------------------------------------
885  copyGlobalAttributes(rootGroup_r, rootGroup_w);
886 
887  // write modified global attrbutes
888  NCDIE(nc_put_att_float(rootGroup_w, NC_GLOBAL, "start_center_longitude", NC_FLOAT, 1, &startCenterLon));
889  NCDIE(nc_put_att_float(rootGroup_w, NC_GLOBAL, "start_center_latitude", NC_FLOAT, 1, &startCenterLat));
890  NCDIE(nc_put_att_float(rootGroup_w, NC_GLOBAL, "end_center_longitude", NC_FLOAT, 1, &endCenterLon));
891  NCDIE(nc_put_att_float(rootGroup_w, NC_GLOBAL, "end_center_latitude", NC_FLOAT, 1, &endCenterLat));
892 
893  NCDIE(nc_put_att_float(rootGroup_w, NC_GLOBAL, "northernmost_latitude", NC_FLOAT, 1, &geoLatMax));
894  NCDIE(nc_put_att_float(rootGroup_w, NC_GLOBAL, "southernmost_latitude", NC_FLOAT, 1, &geoLatMin));
895  NCDIE(nc_put_att_float(rootGroup_w, NC_GLOBAL, "easternmost_longitude", NC_FLOAT, 1, &geoLonMax));
896  NCDIE(nc_put_att_float(rootGroup_w, NC_GLOBAL, "westernmost_longitude", NC_FLOAT, 1, &geoLonMin));
897 
898  NCDIE(nc_put_att_float(rootGroup_w, NC_GLOBAL, "geospatial_lat_max", NC_FLOAT, 1, &geoLatMax));
899  NCDIE(nc_put_att_float(rootGroup_w, NC_GLOBAL, "geospatial_lat_min", NC_FLOAT, 1, &geoLatMin));
900  NCDIE(nc_put_att_float(rootGroup_w, NC_GLOBAL, "geospatial_lon_max", NC_FLOAT, 1, &geoLonMax));
901  NCDIE(nc_put_att_float(rootGroup_w, NC_GLOBAL, "geospatial_lon_min", NC_FLOAT, 1, &geoLonMin));
902  nc_close(rootGroup_r);
903  nc_close(rootGroup_w);
904 
905  free(latArray);
906  free(lonArray);
907  free(flagArray);
908 
909  return EXIT_SUCCESS;
910 }
#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:606
#define NCDIE(function)
#define NULL
Definition: decode_rs.h:63
void copyVariableAttributes(int ncid_r, int varid_r, int ncid_w, int varid_w)
ds_format_t fftype
Definition: dfutils.h:31
void copyVariableSelectedIndexes(int ncid_r, const char *name, size_t *start, size_t *count, int *dimIds, int ncid_w, void *data, int *indexes, int dim_of_indexes)
copy a piece of a variable and all of it's attributes to another file. Slicing is performed along a s...
int32_t prodlist(int32_t sensorID, int32_t evalmask, const char *inprod, const char *defprod, char outprod[L1_MAXPROD][32])
void set_attributes(const char *name, int ncid_r, int ncid_w, int varid_r, int *varid_w, int *dimIds, size_t *chunkSize, int *deflateLevel, int *shuffle, int *numAtts, size_t *chunkNelems, float *chunkPreemption, int *deflate, size_t *typeSize, int *numDims, nc_type *xtype)
Copies all the attributes and chunking/compression properties.
char * readAttrStr(idDS ds_id, const char *name)
Definition: wrapper.c:99
char * strdup(const char *)
idDS startDS(const char *filename, ds_format_t format, ds_access_t accessmode, int32_t deflate)
Definition: wrapper.c:558
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)
int extractNetCDF(const char *infile, const char *outfile, int spix, int epix, int sscan, int escan, const char *prodlist, const char *wavelist)
@ 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")
void get_wv3_indexes(const char *inp_file, const char *wv_list, int **wv_vals_out, int **wv_indexes_out, int *wv_num_to_pass, const char *prod_list)
Get the wv3 indexes object.
#define NAVFAIL
Definition: l2_flags.h:36
int count
Definition: decode_rs.h:79