22 #define MAX_VARIABLES 128
24 #define NCDIE(function){ \
25 int status = function; \
27 case NC_NOERR: break; \
28 default: printf("NetCDF error: file %s, line %d, %s\n", \
29 __FILE__, __LINE__, nc_strerror(status)); \
37 char name[NC_MAX_NAME + 1];
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));
49 char name[NC_MAX_NAME + 1];
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));
67 if (cptr !=
NULL)
return 1;
88 int* dimIds,
int ncid_w,
void*
data) {
98 float chunkPreemption;
104 static int localDataSize = 0;
105 static char* localData =
NULL;
111 status = nc_inq_varid(ncid_r,
name, &varid_r);
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,
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,
127 NCDIE(nc_inq_type(ncid_r, xtype,
NULL, &typeSize));
131 arraySize = typeSize;
132 for (
i = 0;
i < numDims;
i++) {
137 if (arraySize > localDataSize) {
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);
150 NCDIE(nc_put_var(ncid_w, varid_w, localData));
152 NCDIE(nc_put_var(ncid_w, varid_w,
data));
171 int sscan,
int escan,
const char* prodlist) {
174 idDS ds_id_r, ds_id_w;
183 size_t start[3] = {0, 0, 0};
184 size_t count[3] = {1, 1, 1};
185 int dimIds[3] = {0, 0, 0};
189 size_t numPixelControlPoints_r;
192 size_t numPixelControlPoints_w;
193 size_t numTotalBands;
194 size_t numVisibleBands;
199 int numControlPointsDimId;
200 int numTotalBandsDimId;
201 int numVisibleBandsDimId;
216 if (ds_id_r.
fid == -1) {
217 printf(
"could not open \"%s\" for reading.\n",
infile);
221 printf(
"could not open \"%s\" is not a netCDF4 file.\n",
infile);
224 rootGroup_r = ds_id_r.
fid;
228 status = nc_inq_dimid(rootGroup_r,
"number_of_lines", &dim_id);
230 nc_inq_dimid(rootGroup_r,
"Number_of_Scan_Lines", &dim_id);
232 nc_inq_dimlen(rootGroup_r, dim_id, &numLines_r);
233 status = nc_inq_dimid(rootGroup_r,
"pixels_per_line", &dim_id);
235 nc_inq_dimid(rootGroup_r,
"Pixels_per_Scan_Line", &dim_id);
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);
243 nc_inq_dimid(rootGroup_r,
"total_band_number", &dim_id);
245 nc_inq_dimlen(rootGroup_r, dim_id, &numTotalBands);
246 status = nc_inq_dimid(rootGroup_r,
"number_of_reflective_bands", &dim_id);
248 nc_inq_dimid(rootGroup_r,
"band_number", &dim_id);
250 nc_inq_dimlen(rootGroup_r, dim_id, &numVisibleBands);
254 printf(
"\"%s\" is not a L2 file.\n",
infile);
261 if (sscan >= numLines_r) {
262 printf(
"sscan needs to be less than number of scans in file.\n");
265 if (escan < 1 || escan > numLines_r) {
269 printf(
"escan needs to be greater than sscan.\n");
272 numLines_w = escan - sscan + 1;
277 if (
spix >= numPixels_r) {
278 printf(
"spix needs to be less than number of pixels in file.\n");
281 if (epix < 1 || epix > numPixels_r) {
285 printf(
"epix needs to be greater than spix.\n");
293 status = nc_inq_ncid(rootGroup_r,
"geophysical_data", &group_r);
295 printf(
"-E- Could not open \"geophysical_data\" group.\n");
300 word = strtok(tmpProdList,
",");
303 status = nc_inq_varid(group_r, word, &varid);
305 printf(
"-E- Could not find product \"%s\" in L2 file.\n",
310 word = strtok(
NULL,
",");
318 nc_inq_ncid(rootGroup_r,
"navigation_data", &group_r);
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");
328 count[0] = numPixelControlPoints_r;
329 NCDIE(nc_inq_varid(group_r,
"cntl_pt_cols", &varid));
333 for (
i = 0;
i < numPixelControlPoints_r;
i++) {
334 if (cntl_pt_cols[
i] >=
spix) {
339 if (
i >= numPixelControlPoints_r) {
340 printf(
"start pixel control point not found.\n");
345 if (cntl_pt_cols[s_cntl_pt] >
spix) {
348 spix = cntl_pt_cols[s_cntl_pt];
352 e_cntl_pt = numPixelControlPoints_r - 1;
353 for (
i = 0;
i < numPixelControlPoints_r;
i++) {
354 if (cntl_pt_cols[
i] >
epix) {
360 printf(
"sscan: %d escan: %d\n", sscan, escan);
361 printf(
"spixl: %d epixl: %d\n",
spix,
epix);
364 numPixelControlPoints_w = e_cntl_pt - s_cntl_pt + 1;
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");
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));
379 NCDIE(nc_inq_varid(group_r,
"longitude", &varid));
385 nc_inq_ncid(rootGroup_r,
"geophysical_data", &group_r);
387 flagArray = malloc(numLines_w * numPixels_w *
sizeof (
int));
388 if (flagArray ==
NULL) {
389 printf(
"could not allocate memory for flag array\n");
392 start[0] = sscan - 1;
394 count[0] = numLines_w;
395 count[1] = numPixels_w;
396 NCDIE(nc_inq_varid(group_r,
"l2_flags", &varid));
402 #define GEOBOX_INC 20.0
407 int ccol = numPixelControlPoints_w / 2;
408 int line, scol, ecol;
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];
417 float startCenterLat, startCenterLon;
418 float endCenterLat, endCenterLon;
419 float geoLatMin, geoLatMax;
420 float geoLonMin, geoLonMax;
424 lineStart = numPixelControlPoints_w*
line;
428 for (scol = 0; scol <= ccol; scol++) {
430 if (flagArray[
line * numPixels_w + cntl_pt_cols[scol] - 1] ^
NAVFAIL) {
432 geobox[0][geobox_cnt] = lonArray[lineStart + scol];
433 geobox[1][geobox_cnt] = latArray[lineStart + scol];
442 if (flagArray[
line * numPixels_w + cntl_pt_cols[ccol] - 1] ^
NAVFAIL) {
444 startCenterLon = lonArray[lineStart + ccol];
445 startCenterLat = latArray[lineStart + ccol];
446 last_lat = startCenterLat;
452 for (ecol = numPixelControlPoints_w - 1; ecol >= ccol; ecol--) {
454 if (flagArray[
line * numPixels_w + cntl_pt_cols[ecol] - 1] ^
NAVFAIL) {
456 geobox[2][geobox_cnt] = lonArray[lineStart + ecol];
457 geobox[3][geobox_cnt] = latArray[lineStart + ecol];
463 if (startDone && centerDone && endDone)
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;
487 lineStart = numPixelControlPoints_w*
line;
490 for (scol = 0; scol <= ccol; scol++) {
492 if (flagArray[
line * numPixels_w + cntl_pt_cols[scol] - 1] ^
NAVFAIL)
499 for (ecol = numPixelControlPoints_w - 1; ecol >= ccol; ecol--) {
501 if (flagArray[
line * numPixels_w + cntl_pt_cols[ecol] - 1] ^
NAVFAIL)
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];
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];
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];
541 lineStart = numPixelControlPoints_w*lastGoodLine;
544 for (scol = 0; scol < ccol; scol++) {
546 if (flagArray[lastGoodLine * numPixels_w + cntl_pt_cols[scol] - 1] ^
NAVFAIL)
551 for (ecol = numPixelControlPoints_w - 1; ecol >= ccol; ecol--) {
553 if (flagArray[lastGoodLine * numPixels_w + cntl_pt_cols[ecol] - 1] ^
NAVFAIL)
557 endCenterLon = lonArray[lineStart + ccol];
558 endCenterLat = latArray[lineStart + ccol];
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];
568 if (access(outfile, F_OK) != -1) {
569 if (unlink(outfile)) {
570 printf(
"could not delete existing output file %s\n", outfile);
575 rootGroup_w = ds_id_w.
fid;
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));
588 nc_inq_ncid(rootGroup_r,
"sensor_band_parameters", &group_r);
589 nc_def_grp(rootGroup_w,
"sensor_band_parameters", &group_w);
593 count[0] = numVisibleBands;
594 dimIds[0] = numVisibleBandsDimId;
597 status = nc_inq_varids(group_r, &numVariables, variableIds);
600 printf(
"-E- %s %d: too many variables in group \"sensor_band_parameters\"\n",
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;
610 count[0] = numVisibleBands;
611 dimIds[0] = numVisibleBandsDimId;
621 nc_inq_ncid(rootGroup_r,
"scan_line_attributes", &group_r);
622 nc_def_grp(rootGroup_w,
"scan_line_attributes", &group_w);
625 start[0] = sscan - 1;
626 count[0] = numLines_w;
627 dimIds[0] = numLinesDimId;
630 status = nc_inq_varids(group_r, &numVariables, variableIds);
633 printf(
"-E- %s %d: too many variables in group \"scan_line_attributes\"\n",
637 for (
i = 0;
i < numVariables;
i++) {
638 status = nc_inq_varname(group_r, variableIds[
i],
name);
646 nc_inq_ncid(rootGroup_r,
"geophysical_data", &group_r);
647 nc_def_grp(rootGroup_w,
"geophysical_data", &group_w);
650 start[0] = sscan - 1;
652 count[0] = numLines_w;
653 count[1] = numPixels_w;
654 dimIds[0] = numLinesDimId;
655 dimIds[1] = numPixelsDimId;
658 status = nc_inq_varids(group_r, &numVariables, variableIds);
661 printf(
"-E- %s %d: too many variables in group \"scan_line_attributes\"\n",
665 for (
i = 0;
i < numVariables;
i++) {
666 status = nc_inq_varname(group_r, variableIds[
i],
name);
675 nc_inq_ncid(rootGroup_r,
"navigation_data", &group_r);
676 nc_def_grp(rootGroup_w,
"navigation_data", &group_w);
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;
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;
694 count[0] = numPixelControlPoints_w;
695 dimIds[0] = numControlPointsDimId;
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");
705 for (
i = 0;
i < numLines_w;
i++) {
706 cntl_pt_rows[
i] =
i + 1;
708 start[0] = sscan - 1;
709 count[0] = numLines_w;
710 dimIds[0] = numLinesDimId;
717 gring_fval[0] = geobox[0][0];
718 for (
i = 0;
i < geobox_cnt;
i++) {
719 gring_fval[
j++] = geobox[2][
i];
721 for (
i = 0;
i < geobox_cnt - 1;
i++) {
722 gring_fval[
j++] = geobox[0][geobox_cnt - 1 -
i];
724 NCDIE(nc_put_att_float(group_w, NC_GLOBAL,
"gringpointlongitude", NC_FLOAT,
j, gring_fval));
727 gring_fval[0] = geobox[1][0];
729 for (
i = 0;
i < geobox_cnt;
i++) {
730 gring_ival[
j] =
j + 1;
731 gring_fval[
j++] = geobox[3][
i];
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];
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));
743 nc_inq_ncid(rootGroup_r,
"processing_control", &group_r);
744 nc_def_grp(rootGroup_w,
"processing_control", &group_w);
749 nc_inq_ncid(group_r,
"input_parameters", &subGroup_r);
750 nc_def_grp(group_w,
"input_parameters", &subGroup_w);
755 nc_inq_ncid(group_r,
"flag_percentages", &subGroup_r);
756 nc_def_grp(group_w,
"flag_percentages", &subGroup_w);
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));
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));
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));
781 nc_close(rootGroup_r);
782 nc_close(rootGroup_w);