23 #define MAX_VARIABLES 512
25 #define NCDIE(function) \
27 int status = function; \
32 printf("NetCDF error: file %s, line %d, %s\n", __FILE__, __LINE__, nc_strerror(status)); \
40 char name[NC_MAX_NAME + 1];
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));
52 char name[NC_MAX_NAME + 1];
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));
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) {
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));
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));
117 NCDIE(nc_inq_type(ncid_r, *xtype,
NULL, typeSize));
141 float chunkPreemption;
147 static int localDataSize = 0;
148 static char *localData =
NULL;
154 status = nc_inq_varid(ncid_r,
name, &varid_r);
157 &numAtts, &chunkNelems, &chunkPreemption, &deflate, &typeSize, &numDims, &xtype);
160 arraySize = typeSize;
161 for (
i = 0;
i < numDims;
i++) {
166 if (arraySize > localDataSize) {
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);
177 NCDIE(nc_put_var(ncid_w, varid_w, localData));
179 NCDIE(nc_put_var(ncid_w, varid_w,
data));
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);
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++) {
222 float chunkPreemption;
228 static int localDataSize = 0;
229 static char *localData =
NULL;
235 status = nc_inq_varid(ncid_r,
name, &varid_r);
238 &numAtts, &chunkNelems, &chunkPreemption, &deflate, &typeSize, &numDims, &xtype);
241 arraySize = typeSize;
242 if (dim_of_indexes >= numDims) {
244 "Supplied dim_of_indexes execedes the number of dimensions "
246 dim_of_indexes, numDims);
249 for (
i = 0;
i < numDims;
i++) {
250 if (
i == dim_of_indexes)
252 arraySize *= count_global[
i];
253 count_local[
i] = count_global[
i];
257 if (arraySize > localDataSize) {
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);
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));
276 NCDIE(nc_put_var(ncid_w, varid_w,
data));
294 const char *prodlist,
const char *wavelist) {
296 idDS ds_id_r, ds_id_w;
305 size_t start[3] = {0, 0, 0};
306 size_t count[3] = {1, 1, 1};
307 int dimIds[3] = {0, 0, 0};
313 size_t numTotalBands;
314 size_t numVisibleBands;
315 size_t numBandsPerPixel;
316 size_t numReflectanceLocationValues;
317 size_t number_of_wv_3d = 0;
318 int reflectanceLocationValuesFound = 0;
321 int numBandsPerPixelDimId;
322 int numReflectiveLocationValuesDimId;
323 int numTotalBandsDimId;
324 int numVisibleBandsDimId;
333 float *latArray =
NULL;
334 float *lonArray =
NULL;
335 int *flagArray =
NULL;
337 int *wv_values_to_pass =
NULL;
338 int *wv_indexes_to_pass =
NULL;
339 int wv_num_to_pass = 0;
344 if (ds_id_r.
fid == -1) {
345 printf(
"could not open \"%s\" for reading.\n",
infile);
349 printf(
"could not open \"%s\" is not a netCDF4 file.\n",
infile);
352 rootGroup_r = ds_id_r.
fid;
356 status = nc_inq_dimid(rootGroup_r,
"number_of_lines", &dim_id);
358 nc_inq_dimid(rootGroup_r,
"Number_of_Scan_Lines", &dim_id);
360 nc_inq_dimlen(rootGroup_r, dim_id, &numLines_r);
362 status = nc_inq_dimid(rootGroup_r,
"pixels_per_line", &dim_id);
364 nc_inq_dimid(rootGroup_r,
"Pixels_per_Scan_Line", &dim_id);
366 nc_inq_dimlen(rootGroup_r, dim_id, &numPixels_r);
368 status = nc_inq_dimid(rootGroup_r,
"number_of_bands", &dim_id);
370 nc_inq_dimid(rootGroup_r,
"total_band_number", &dim_id);
372 nc_inq_dimlen(rootGroup_r, dim_id, &numTotalBands);
374 status = nc_inq_dimid(rootGroup_r,
"number_of_reflective_bands", &dim_id);
376 nc_inq_dimid(rootGroup_r,
"band_number", &dim_id);
378 nc_inq_dimlen(rootGroup_r, dim_id, &numVisibleBands);
380 status = nc_inq_dimid(rootGroup_r,
"bands_per_pixel", &dim_id);
382 nc_inq_dimlen(rootGroup_r, dim_id, &numBandsPerPixel);
384 numBandsPerPixel = numTotalBands;
387 status = nc_inq_dimid(rootGroup_r,
"wavelength_3d", &dim_id);
389 nc_inq_dimlen(rootGroup_r, dim_id, &number_of_wv_3d);
391 status = nc_inq_dimid(rootGroup_r,
"number_of_reflectance_location_values", &dim_id);
393 nc_inq_dimlen(rootGroup_r, dim_id, &numReflectanceLocationValues);
394 reflectanceLocationValuesFound = 1;
399 printf(
"\"%s\" is not a L2 file.\n",
infile);
407 if (sscan >= numLines_r) {
408 printf(
"sscan needs to be less than number of scans in file.\n");
411 if (escan < 1 || escan > numLines_r) {
415 printf(
"escan needs to be greater than sscan.\n");
418 numLines_w = escan - sscan + 1;
423 if (
spix >= numPixels_r) {
424 printf(
"spix needs to be less than number of pixels in file.\n");
427 if (epix < 1 || epix > numPixels_r) {
431 printf(
"epix needs to be greater than spix.\n");
439 status = nc_inq_ncid(rootGroup_r,
"geophysical_data", &group_r);
441 printf(
"-E- Could not open \"geophysical_data\" group.\n");
446 word = strtok(tmpProdList,
",");
449 status = nc_inq_varid(group_r, word, &varid);
451 printf(
"-E- Could not find product \"%s\" in L2 file.\n", word);
455 word = strtok(
NULL,
",");
463 nc_inq_ncid(rootGroup_r,
"navigation_data", &group_r);
465 printf(
"sscan: %d escan: %d\n", sscan, escan);
466 printf(
"spixl: %d epixl: %d\n",
spix,
epix);
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");
477 start[0] = sscan - 1;
479 count[0] = numLines_w;
480 count[1] = numPixels_w;
481 NCDIE(nc_inq_varid(group_r,
"latitude", &varid));
483 NCDIE(nc_inq_varid(group_r,
"longitude", &varid));
489 nc_inq_ncid(rootGroup_r,
"geophysical_data", &group_r);
491 flagArray = malloc(numLines_w * numPixels_w *
sizeof(
int));
492 if (flagArray ==
NULL) {
493 printf(
"could not allocate memory for flag array\n");
496 start[0] = sscan - 1;
498 count[0] = numLines_w;
499 count[1] = numPixels_w;
500 NCDIE(nc_inq_varid(group_r,
"l2_flags", &varid));
505 #define GEOBOX_INC 20.0
510 int ccol = numPixels_w / 2;
511 int line, scol, ecol;
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];
520 float startCenterLat, startCenterLon;
521 float endCenterLat, endCenterLon;
522 float geoLatMin, geoLatMax;
523 float geoLonMin, geoLonMax;
527 lineStart = numPixels_w *
line;
531 for (scol = 0; scol <= ccol; scol++) {
533 if (flagArray[
line * numPixels_w + scol] ^
NAVFAIL) {
535 geobox[0][geobox_cnt] = lonArray[lineStart + scol];
536 geobox[1][geobox_cnt] = latArray[lineStart + scol];
545 if (flagArray[
line * numPixels_w + ccol] ^
NAVFAIL) {
547 startCenterLon = lonArray[lineStart + ccol];
548 startCenterLat = latArray[lineStart + ccol];
549 last_lat = startCenterLat;
555 for (ecol = numPixels_w - 1; ecol >= ccol; ecol--) {
557 if (flagArray[
line * numPixels_w + ecol] ^
NAVFAIL) {
559 geobox[2][geobox_cnt] = lonArray[lineStart + ecol];
560 geobox[3][geobox_cnt] = latArray[lineStart + ecol];
566 if (startDone && centerDone && endDone)
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;
590 lineStart = numPixels_w *
line;
593 for (scol = 0; scol <= ccol; scol++) {
595 if (flagArray[
line * numPixels_w + scol] ^
NAVFAIL)
602 for (ecol = numPixels_w - 1; ecol >= ccol; ecol--) {
604 if (flagArray[
line * numPixels_w + ecol] ^
NAVFAIL)
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];
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];
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];
644 lineStart = numPixels_w * lastGoodLine;
647 for (scol = 0; scol < ccol; scol++) {
649 if (flagArray[lastGoodLine * numPixels_w + scol] ^
NAVFAIL)
654 for (ecol = numPixels_w - 1; ecol >= ccol; ecol--) {
656 if (flagArray[lastGoodLine * numPixels_w + ecol] ^
NAVFAIL)
660 endCenterLon = lonArray[lineStart + ccol];
661 endCenterLat = latArray[lineStart + ccol];
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];
671 if (access(
outfile, F_OK) != -1) {
673 printf(
"could not delete existing output file %s\n",
outfile);
678 rootGroup_w = ds_id_w.
fid;
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;
689 NCDIE(nc_def_dim(rootGroup_w,
"wavelength_3d", number_of_wv_3d, &numwv3dDimId));
692 if (reflectanceLocationValuesFound) {
693 NCDIE(nc_def_dim(rootGroup_w,
"number_of_reflectance_location_values", numReflectanceLocationValues,
694 &numReflectiveLocationValuesDimId));
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));
702 nc_inq_ncid(rootGroup_r,
"sensor_band_parameters", &group_r);
703 nc_def_grp(rootGroup_w,
"sensor_band_parameters", &group_w);
707 count[0] = numVisibleBands;
708 dimIds[0] = numVisibleBandsDimId;
711 status = nc_inq_varids(group_r, &numVariables, variableIds);
714 printf(
"-E- %s %d: too many variables in group \"sensor_band_parameters\"\n",
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;
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) {
730 wv_indexes_to_pass, 0);
734 count[0] = numVisibleBands;
735 dimIds[0] = numVisibleBandsDimId;
745 nc_inq_ncid(rootGroup_r,
"scan_line_attributes", &group_r);
746 nc_def_grp(rootGroup_w,
"scan_line_attributes", &group_w);
749 start[0] = sscan - 1;
750 count[0] = numLines_w;
751 dimIds[0] = numLinesDimId;
754 status = nc_inq_varids(group_r, &numVariables, variableIds);
757 printf(
"-E- %s %d: too many variables in group \"scan_line_attributes\"\n",
761 for (
i = 0;
i < numVariables;
i++) {
762 status = nc_inq_varname(group_r, variableIds[
i],
name);
770 nc_inq_ncid(rootGroup_r,
"geophysical_data", &group_r);
771 nc_def_grp(rootGroup_w,
"geophysical_data", &group_w);
774 start[0] = sscan - 1;
776 count[0] = numLines_w;
777 count[1] = numPixels_w;
778 dimIds[0] = numLinesDimId;
779 dimIds[1] = numPixelsDimId;
782 status = nc_inq_varids(group_r, &numVariables, variableIds);
785 printf(
"-E- %s %d: too many variables in group \"geophysical_data\"\n",
789 for (
i = 0;
i < numVariables;
i++) {
790 status = nc_inq_varname(group_r, variableIds[
i],
name);
792 int varids_dims[3] = {0, 0, 0};
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) {
803 wv_indexes_to_pass, 2);
820 nc_inq_ncid(rootGroup_r,
"navigation_data", &group_r);
821 nc_def_grp(rootGroup_w,
"navigation_data", &group_w);
823 start[0] = sscan - 1;
825 count[0] = numLines_w;
826 count[1] = numPixels_w;
827 dimIds[0] = numLinesDimId;
828 dimIds[1] = numPixelsDimId;
832 start[0] = sscan - 1;
833 count[0] = numLines_w;
834 dimIds[0] = numLinesDimId;
839 gring_fval[0] = geobox[0][0];
840 for (
i = 0;
i < geobox_cnt;
i++) {
841 gring_fval[
j++] = geobox[2][
i];
843 for (
i = 0;
i < geobox_cnt - 1;
i++) {
844 gring_fval[
j++] = geobox[0][geobox_cnt - 1 -
i];
846 NCDIE(nc_put_att_float(group_w, NC_GLOBAL,
"gringpointlongitude", NC_FLOAT,
j, gring_fval));
849 gring_fval[0] = geobox[1][0];
851 for (
i = 0;
i < geobox_cnt;
i++) {
852 gring_ival[
j] =
j + 1;
853 gring_fval[
j++] = geobox[3][
i];
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];
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));
865 nc_inq_ncid(rootGroup_r,
"processing_control", &group_r);
866 nc_def_grp(rootGroup_w,
"processing_control", &group_w);
871 nc_inq_ncid(group_r,
"input_parameters", &subGroup_r);
872 nc_def_grp(group_w,
"input_parameters", &subGroup_w);
877 nc_inq_ncid(group_r,
"flag_percentages", &subGroup_r);
878 nc_def_grp(group_w,
"flag_percentages", &subGroup_w);
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));
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));
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);