21 static double ***f_cal_corr =
NULL;
27 static int extract_pixel_start = 0;
28 static int extract_pixel_stop = 0;
40 static const char* SCN_GRP =
"scan_line_attributes";
51 static const varlist VARLIST_SCN[] = {
63 static const char*
NAV_GRP =
"navigation_data";
78 static const varlist VARLIST_NAV[] = {
94 static const char* GEO_GRP =
"geolocation_data";
109 static const varlist VARLIST_GEO[] = {
135 static const varlist VARLIST_L1BSCN[] = {
146 static const char* L1B_GRP =
"observation_data";
152 static const varlist VARLIST_L1B[] = {
176 static float latGeoFillValue = -999.9;
177 static float lonGeoFillValue = -999.9;
178 static short senzGeoFillValue = -32768;
179 static short senaGeoFillValue = -32768;
180 static short solzGeoFillValue = -32768;
181 static short solaGeoFillValue = -32768;
183 static float latL2FillValue = -999.0;
184 static float lonL2FillValue = -999.0;
185 static float senzL2FillValue = -32767;
186 static float senaL2FillValue = -32767;
187 static float solzL2FillValue = -32767;
188 static float solaL2FillValue = -32767;
208 printf(
"file:\t%s\n", info.file);
209 printf(
"title:\t%s\n", info.title);
210 printf(
"time range:\t%s %s\n", info.start_time, info.end_time);
211 printf(
"orbit: \t%d\n", info.orbit_number);
212 printf(
"nscans =\t%d\n", (
int) info.nscans);
213 printf(
"nlines =\t%d\n", (
int) info.nlines);
214 printf(
"npixls =\t%d\n", (
int) info.npixls);
219 int32_t grpid, varid, dimid;
224 bzero(info,
sizeof(*info));
226 status = nc_open(info->file, NC_NOWRITE, &info->id);
228 printf(
"-E- init_viirs_file - Could not open netCDF file \"%s\"\n", info->file);
234 nc_inq_dimid(info->id,
"number_of_scans", &dimid);
235 nc_inq_dimlen(info->id, dimid, &info->nscans);
236 nc_inq_dimid(info->id,
"number_of_lines", &dimid);
237 nc_inq_dimlen(info->id, dimid, &info->nlines);
238 nc_inq_dimid(info->id,
"number_of_pixels", &dimid);
239 nc_inq_dimlen(info->id, dimid, &info->npixls);
242 nc_get_att_text(info->id, NC_GLOBAL,
243 "title", (
char*) &info->title);
244 nc_inq_attlen(info->id, NC_GLOBAL,
"title", &attlen);
245 info->title[attlen] =
'\0';
247 nc_get_att_text(info->id, NC_GLOBAL,
248 "time_coverage_start", (
char*) &info->start_time);
249 nc_inq_attlen(info->id, NC_GLOBAL,
"time_coverage_start", &attlen);
250 info->start_time[attlen] =
'\0';
252 nc_get_att_text(info->id, NC_GLOBAL,
253 "time_coverage_end", (
char*) &info->end_time);
254 nc_inq_attlen(info->id, NC_GLOBAL,
"time_coverage_end", &attlen);
255 info->end_time[attlen] =
'\0';
260 if ((nc_inq_att(info->id, NC_GLOBAL,
"orbit_number", &vr_type, &vr_len) == NC_NOERR)) {
261 nc_get_att_int(info->id, NC_GLOBAL,
262 "orbit_number", &info->orbit_number);
264 nc_get_att_int(info->id, NC_GLOBAL,
265 "OrbitNumber", &info->orbit_number);
268 if ((nc_inq_att(info->id, NC_GLOBAL,
"extract_pixel_start", &vr_type, &vr_len) == NC_NOERR)) {
269 nc_get_att_int(info->id, NC_GLOBAL,
270 "extract_pixel_start", &extract_pixel_start);
271 extract_pixel_start--;
272 nc_get_att_int(info->id, NC_GLOBAL,
273 "extract_pixel_stop", &extract_pixel_stop);
274 extract_pixel_stop--;
278 nc_inq_grp_ncid(info->id,
"scan_line_attributes", &grpid);
279 nc_inq_varid(grpid,
"scan_start_time", &varid);
280 TRYMEM(__FILE__, __LINE__,
281 (info->scan_start_time = malloc(info->nscans *
282 sizeof(*info->scan_start_time))));
283 nc_get_var_double(grpid, varid, info->scan_start_time);
295 "VIIRS M-band Reflected Solar Band and Thermal Emissive Band Data";
297 char qaname[FILENAME_MAX + 1];
302 "Input file %s has unexpected product title!\n"
303 "Expected:\t\"%s\"\n"
304 "Actual: \t\"%s\"\n",
327 sprintf(qaname,
"%s%s", VARLIST_L1B[
i].
name,
"_quality_flags");
338 const char*
title =
"VIIRS M-band Geolocation Data";
344 "Input file %s has unexpected product title!\n"
345 "Expected:\t\"%s\"\n"
346 "Actual: \t\"%s\"\n",
360 TRY_NC(__FILE__, __LINE__,
361 nc_get_att_float(geo[
GEO_LAT]->grpid, geo[
GEO_LAT]->
id,
"_FillValue", &latGeoFillValue));
362 TRY_NC(__FILE__, __LINE__,
363 nc_get_att_float(geo[
GEO_LON]->grpid, geo[
GEO_LON]->
id,
"_FillValue", &lonGeoFillValue));
364 TRY_NC(__FILE__, __LINE__,
365 nc_get_att_short(geo[
GEO_SENZ]->grpid, geo[
GEO_SENZ]->
id,
"_FillValue", &senzGeoFillValue));
366 TRY_NC(__FILE__, __LINE__,
367 nc_get_att_short(geo[
GEO_SENA]->grpid, geo[
GEO_SENA]->
id,
"_FillValue", &senaGeoFillValue));
368 TRY_NC(__FILE__, __LINE__,
369 nc_get_att_short(geo[
GEO_SOLZ]->grpid, geo[
GEO_SOLZ]->
id,
"_FillValue", &solzGeoFillValue));
370 TRY_NC(__FILE__, __LINE__,
371 nc_get_att_short(geo[
GEO_SOLA]->grpid, geo[
GEO_SOLA]->
id,
"_FillValue", &solaGeoFillValue));
378 latL2FillValue = info->fillValue;
381 lonL2FillValue = info->fillValue;
384 senaL2FillValue = info->fillValue;
387 senzL2FillValue = info->fillValue;
390 solaL2FillValue = info->fillValue;
393 solzL2FillValue = info->fillValue;
406 char *tmpStr = malloc(strlen(VARLIST_NAV[
i].
name) + 5);
407 sprintf(tmpStr,
"%s_mid", VARLIST_NAV[
i].
name);
410 printf(
"-E- init_viirs_geofile - could not find variable %s in the geo file\n", VARLIST_NAV[
i].
name);
432 printf(
"-E- openl1b_viirs_nc - VIIRS L1B files require a GEO file.\n");
444 l1file->terrain_corrected = 1;
455 fprintf(
stderr,
"Geometry mismatch!\n");
456 fprintf(
stderr,
"L1B: nscans = %3d, nlines = %4d, npixls = %4d\n",
458 fprintf(
stderr,
"GEO: nscans = %3d, nlines = %4d, npixls = %4d\n",
468 fprintf(
stderr,
"Time coverage mismatch!\n");
469 fprintf(
stderr,
"L1B: Orbit %6d, %s - %s\n",
471 fprintf(
stderr,
"GEO: Orbit %6d, %s - %s\n",
480 fprintf(
stderr,
"Scan time mismatch!\n");
481 fprintf(
stderr,
"Scan %d\tL1B=%f\tGEO=%f\tdiff=%f\n",
497 "Fobar", (
void **) &Fobar);
503 grantime += 1104537600.0;
504 grantime *= 1000000.0;
520 size_t start[2] = {0, 0};
521 size_t count[2] = {1, 1};
523 if (var->
ndims == 2) {
527 TRY_NC(__FILE__, __LINE__,
528 nc_inq_type(var->
id, var->
type,
NULL, &typesize));
532 TRYMEM(__FILE__, __LINE__,
533 (var->
data = calloc(npixl, typesize)));
539 TRY_NC(__FILE__, __LINE__,
550 short tmpval, fillval;
551 short minval, maxval;
555 TRY_NC(__FILE__, __LINE__,
556 nc_get_att_short(var->
grpid, var->
id,
"_FillValue", &fillval));
557 TRY_NC(__FILE__, __LINE__,
558 nc_get_att_short(var->
grpid, var->
id,
"valid_min", &minval));
559 TRY_NC(__FILE__, __LINE__,
560 nc_get_att_short(var->
grpid, var->
id,
"valid_max", &maxval));
561 TRY_NC(__FILE__, __LINE__,
562 nc_get_att_float(var->
grpid, var->
id,
"scale_factor", &
scale));
563 TRY_NC(__FILE__, __LINE__,
564 nc_get_att_float(var->
grpid, var->
id,
"add_offset", &
offset));
566 for (ipix = 0; ipix <
npix; ipix++) {
567 tmpval = ((
short *) var->
data)[ipix];
568 if ((tmpval == fillval) ||
571 dest[ipix] = (
float) tmpval;
581 uint32_t tmpval, fillval;
582 uint32_t minval, maxval;
586 size_t ipb, ipix,
npix;
597 for (iband = 0; iband <
MAXBANDS; iband++) {
598 bandtype = VARLIST_L1B[iband].
index;
600 if (l1b[iband] ==
NULL) {
601 if (bandtype ==
TEB) iteb++;
602 if (bandtype ==
RSB) irsb++;
606 TRY_NC(__FILE__, __LINE__,
607 nc_get_att_uint(l1b[iband]->grpid, l1b[iband]->
id,
608 "_FillValue", &fillval));
609 TRY_NC(__FILE__, __LINE__,
610 nc_get_att_uint(l1b[iband]->grpid, l1b[iband]->
id,
611 "valid_min", &minval));
612 TRY_NC(__FILE__, __LINE__,
613 nc_get_att_uint(l1b[iband]->grpid, l1b[iband]->
id,
614 "valid_max", &maxval));
615 TRY_NC(__FILE__, __LINE__,
616 nc_get_att_float(l1b[iband]->grpid, l1b[iband]->
id,
617 "scale_factor", &
scale));
618 TRY_NC(__FILE__, __LINE__,
619 nc_get_att_float(l1b[iband]->grpid, l1b[iband]->
id,
623 f_corr = (f_cal_corr ==
NULL) ? 1.0
624 : f_cal_corr[iband][
l1rec->detnum][
l1rec->mside];
627 if (bandtype ==
TEB) {
628 for (ipix = 0; ipix <
npix; ipix++) {
631 l1rec->Ltir[ipb] = 0;
634 if (strcmp(VARLIST_L1B[iband].
name,
"M13") == 0) {
635 tmpval = ((uint32_t *) l1b[iband]->
data)[ipix];
639 if ((tmpval == fillval) ||
648 l1rec->Ltir[ipb] /= 10.0;
651 l1rec->Ltir[ipb] *= f_corr;
658 else if (bandtype ==
CIR) {
659 for (ipix = 0; ipix <
npix; ipix++) {
664 if ((tmpval == fillval) ||
676 l1rec->rho_cirrus[ipix] *= f_corr;
686 for (ipix = 0; ipix <
npix; ipix++) {
687 ipb = ipix *
l1rec->l1file->nbands + irsb;
696 if ((tmpval == fillval) ||
708 l1rec->Lt[ipb] *= f_corr;
736 float sen_mat[3][3], coeff[10];
749 if (TAI93sec < 0.0) {
762 int32_t yr = (int32_t)
year;
763 int32_t dy = (int32_t)
day;
764 int32_t
msec = (int32_t) (dsec * 1000.0);
788 for (
i = 0;
i < 3;
i++) {
802 for (
i = 0;
i < 3;
i++)
812 for (ivar = 0; ivar <
MAXBANDS; ivar++) {
813 if (l1b[ivar] ==
NULL)
continue;
821 for (ipix = 0; ipix <
l1rec->npix; ipix++) {
822 l1rec->pixnum[ipix] = ipix + extract_pixel_start;
823 if (
l1rec->scantime < 0)
843 if (
l1rec->lat[ipix] == latGeoFillValue)
844 l1rec->lat[ipix] = latL2FillValue;
845 if (
l1rec->lon[ipix] == lonGeoFillValue)
846 l1rec->lon[ipix] = lonL2FillValue;
847 if (
l1rec->sena[ipix] == senaGeoFillValue)
848 l1rec->sena[ipix] = senaL2FillValue;
849 if (
l1rec->senz[ipix] == senzGeoFillValue)
850 l1rec->senz[ipix] = senzL2FillValue;
851 if (
l1rec->sola[ipix] == solaGeoFillValue)
852 l1rec->sola[ipix] = solaL2FillValue;
853 if (
l1rec->solz[ipix] == solzGeoFillValue)
854 l1rec->solz[ipix] = solzL2FillValue;
870 for (ip = 0; ip <
l1rec->npix; ip++) {
872 if (
l1rec->lat[ip] == latGeoFillValue)
873 l1rec->lat[ip] = latL2FillValue;
874 if (
l1rec->lon[ip] == lonGeoFillValue)
875 l1rec->lon[ip] = lonL2FillValue;
882 int pix = ipix + extract_offset;
883 if (pix < AGZONE1 || pix >=
AGZONE5) {
884 if (
l1rec->detnum < 2 ||
l1rec->detnum > 13) {
889 if (
l1rec->detnum == 0 ||
l1rec->detnum == 15) {