17 #define MBAND_NUM_DETECTORS 16
19 static int32_t prevScan = -1;
21 static int scanLineGrp;
22 static int scanStartTimeId;
26 static int geoNavigationGrp;
27 static int geoGeolocationGrp;
28 static int geoScanLineGrp;
29 static int lonId, latId, senzId, senaId, solzId, solaId, angId, posId, velId, scanQualityId, pixelQualityId;
31 static double ***f_cal_corr =
NULL;
34 static int extract_pixel_start = 0;
35 static int extract_pixel_stop = 0;
37 static short *tmpShort;
38 static unsigned char *tmpByte;
41 static double starttime;
42 static double lastvalidtime;
43 static int lastvalidscan = 0;
44 static double time_interval;
46 static float latGeoFillValue = -999.9;
47 static float lonGeoFillValue = -999.9;
48 static short senzGeoFillValue = -32768;
49 static short senaGeoFillValue = -32768;
50 static short solzGeoFillValue = -32768;
51 static short solaGeoFillValue = -32768;
53 static float latL2FillValue = -999.0;
54 static float lonL2FillValue = -999.0;
55 static float senzL2FillValue = -32767;
56 static float senaL2FillValue = -32767;
57 static float solzL2FillValue = -32767;
58 static float solaL2FillValue = -32767;
60 static double scan_start_tai = -999;
73 fprintf(
stderr,
"-E- %s line %d: nc_open(%s) failed.\n",
74 __FILE__, __LINE__,
file->name);
91 if ((nc_inq_att(
fileID, NC_GLOBAL,
"extract_pixel_start", &vr_type, &vr_len) == NC_NOERR)) {
92 status = nc_get_att_int(
fileID, NC_GLOBAL,
"extract_pixel_start", &extract_pixel_start);
94 extract_pixel_start--;
95 status = nc_get_att_int(
fileID, NC_GLOBAL,
"extract_pixel_stop", &extract_pixel_stop);
98 if (
npix != (extract_pixel_stop - extract_pixel_start + 1)) {
99 printf(
"-E- Problem with the extracted L1A file pixel dimension.\n");
100 printf(
" npix(%d), extract_pixel_stop(%d), extract_pixel_start(%d) do not work together.\n",
101 npix, extract_pixel_stop, extract_pixel_start);
107 printf(
"VIIRS L1A Npix :%d Nlines:%d\n",
npix, nline);
111 status = nc_inq_attlen(
fileID, NC_GLOBAL,
"time_coverage_start", &att_len);
115 fltime = (
char *) malloc(att_len + 1);
118 status = nc_get_att_text(
fileID, NC_GLOBAL,
"time_coverage_start", fltime);
120 fltime[att_len] =
'\0';
126 status = nc_inq_attlen(
fileID, NC_GLOBAL,
"time_coverage_end", &att_len);
130 fltime = (
char *) malloc(att_len + 1);
133 status = nc_get_att_text(
fileID, NC_GLOBAL,
"time_coverage_end", fltime);
135 fltime[att_len] =
'\0';
142 if ((nc_inq_att(
fileID, NC_GLOBAL,
"orbit_number", &vr_type, &vr_len) == NC_NOERR)) {
143 status = nc_get_att_int(
fileID, NC_GLOBAL,
"orbit_number", &orbit_number);
146 status = nc_get_att_int(
fileID, NC_GLOBAL,
"OrbitNumber", &orbit_number);
155 file->terrain_corrected = 1;
156 file->orbit_number = orbit_number;
160 "Fobar", (
void **) &Fobar);
163 printf(
"file->nbands = %d\n", (
int)
file->nbands);
165 status = nc_inq_ncid(
file->sd_id,
"scan_line_attributes", &scanLineGrp);
169 status = nc_inq_varid(scanLineGrp,
"scan_start_time", &scanStartTimeId);
173 status = nc_inq_varid(scanLineGrp,
"HAM_side", &HAMSideId);
177 if (
file->geofile &&
file->geofile[0]) {
179 status = nc_open(
file->geofile, NC_NOWRITE, &geoFileId);
181 printf(
"-E- Could not open GEO file \"%s\"\n",
file->geofile);
185 status = nc_inq_grp_ncid(geoFileId,
"geolocation_data", &geoGeolocationGrp);
187 status = nc_inq_varid(geoGeolocationGrp,
"longitude", &lonId);
189 status = nc_inq_var_fill(geoGeolocationGrp, lonId,
NULL, &lonGeoFillValue);
191 status = nc_inq_varid(geoGeolocationGrp,
"latitude", &latId);
193 status = nc_inq_var_fill(geoGeolocationGrp, latId,
NULL, &latGeoFillValue);
195 status = nc_inq_varid(geoGeolocationGrp,
"sensor_zenith", &senzId);
197 status = nc_inq_var_fill(geoGeolocationGrp, senzId,
NULL, &senzGeoFillValue);
199 status = nc_inq_varid(geoGeolocationGrp,
"sensor_azimuth", &senaId);
201 status = nc_inq_var_fill(geoGeolocationGrp, senaId,
NULL, &senaGeoFillValue);
203 status = nc_inq_varid(geoGeolocationGrp,
"solar_zenith", &solzId);
205 status = nc_inq_var_fill(geoGeolocationGrp, solzId,
NULL, &solzGeoFillValue);
207 status = nc_inq_varid(geoGeolocationGrp,
"solar_azimuth", &solaId);
209 status = nc_inq_var_fill(geoGeolocationGrp, solaId,
NULL, &solaGeoFillValue);
211 status = nc_inq_varid(geoGeolocationGrp,
"quality_flag", &pixelQualityId);
214 status = nc_inq_grp_ncid(geoFileId,
"navigation_data", &geoNavigationGrp);
216 status = nc_inq_varid(geoNavigationGrp,
"att_ang_mid", &angId);
218 status = nc_inq_varid(geoNavigationGrp,
"orb_pos_ev_mid", &posId);
220 status = nc_inq_varid(geoNavigationGrp,
"orb_vel_ev_mid", &velId);
223 status = nc_inq_grp_ncid(geoFileId,
"scan_line_attributes", &geoScanLineGrp);
225 status = nc_inq_varid(geoScanLineGrp,
"scan_quality", &scanQualityId);
233 latL2FillValue = info->fillValue;
236 lonL2FillValue = info->fillValue;
239 senaL2FillValue = info->fillValue;
242 senzL2FillValue = info->fillValue;
245 solaL2FillValue = info->fillValue;
248 solzL2FillValue = info->fillValue;
255 static int firstCall = 1;
262 size_t start[] = { 0, 0, 0 };
263 size_t count[] = { 1, 1, 1 };
267 for (ip = 0; ip <
npix; ip++) {
268 l1rec->pixnum[ip] = ip + extract_pixel_start;
275 if (
file->geofile &&
file->geofile[0]) {
279 double grantime = starttime + 378691200.0;
280 grantime *= 1000000.0;
287 tmpShort = (
short *) malloc(
npix *
sizeof(
short));
288 tmpByte = (
unsigned char *) malloc(
npix);
296 if (
scan != prevScan) {
298 status = nc_get_var1_double(scanLineGrp, scanStartTimeId,
start, &scan_start_tai);
302 if (scan_start_tai > 0) {
304 lastvalidscan =
line;
305 l1rec->scantime = lastvalidtime;
307 l1rec->scantime = lastvalidtime + (time_interval * (
line - lastvalidscan));
314 if (!
file->geofile || !
file->geofile[0]) {
329 short scanQualityWarnMask = 2 | 8 | 128;
330 short scanQualityFailMask = 4;
331 static short scanQualityFlag = 0;
333 if (
scan != prevScan) {
335 status = nc_get_var1_short(geoScanLineGrp, scanQualityId,
start, &scanQualityFlag);
338 if (scanQualityFlag & scanQualityFailMask) {
339 for (ip = 0; ip <
npix; ip++)
343 if (scanQualityFlag & scanQualityWarnMask) {
344 for (ip = 0; ip <
npix; ip++)
348 static unsigned char HAMSideVal = 0;
349 if (
scan != prevScan) {
351 status = nc_get_var1_uchar(scanLineGrp, HAMSideId,
start, &HAMSideVal);
354 l1rec->mside = HAMSideVal;
365 if (
l1rec->lat[
i] == latGeoFillValue)
366 l1rec->lat[
i] = latL2FillValue;
371 if (
l1rec->lon[
i] == lonGeoFillValue)
372 l1rec->lon[
i] = lonL2FillValue;
374 status = nc_get_vara_short(geoGeolocationGrp, solzId,
start,
count, tmpShort);
377 if (tmpShort[
i] == solzGeoFillValue)
378 l1rec->solz[
i] = solzL2FillValue;
380 l1rec->solz[
i] = tmpShort[
i] * 0.01;
382 status = nc_get_vara_short(geoGeolocationGrp, solaId,
start,
count, tmpShort);
385 if (tmpShort[
i] == solaGeoFillValue)
386 l1rec->sola[
i] = solaL2FillValue;
388 l1rec->sola[
i] = tmpShort[
i] * 0.01;
390 status = nc_get_vara_short(geoGeolocationGrp, senzId,
start,
count, tmpShort);
393 if (tmpShort[
i] == senzGeoFillValue)
394 l1rec->senz[
i] = senzL2FillValue;
396 l1rec->senz[
i] = tmpShort[
i] * 0.01;
398 status = nc_get_vara_short(geoGeolocationGrp, senaId,
start,
count, tmpShort);
401 if (tmpShort[
i] == senaGeoFillValue)
402 l1rec->sena[
i] = senaL2FillValue;
404 l1rec->sena[
i] = tmpShort[
i] * 0.01;
410 size_t s3[] = {
scan, 0 };
411 size_t c3[] = { 1, 3 };
412 status = nc_get_vara_float(geoNavigationGrp, angId, s3, c3, ang);
414 status = nc_get_vara_float(geoNavigationGrp, posId, s3, c3,
pos);
416 status = nc_get_vara_float(geoNavigationGrp, velId, s3, c3, vel);
418 for (
i = 0;
i < 3;
i++) {
424 float sen_mat[3][3], coeff[10];
427 for (
i = 0;
i < 3;
i++)
434 status = nc_get_vara_uchar(geoGeolocationGrp, pixelQualityId,
start,
count, tmpByte);
439 unsigned char qualityFailMask = 1 | 2;
440 unsigned char qualityWarnMask = 4;
442 if (tmpByte[
i] & qualityFailMask)
444 if (tmpByte[
i] & qualityWarnMask)
449 static double esdist = -999.9;
450 if (
scan != prevScan) {
454 int32_t yr = (int32_t)
year;
455 int32_t dy = (int32_t)
day;
456 int32_t
msec = (int32_t) (dsec * 1000.0);
464 static float *l1bptrs[16] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
465 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
467 static char *bandType[16] = {
"RSB",
"RSB",
"RSB",
"RSB",
"RSB",
"RSB",
468 "RSB",
"RSB",
"CIR",
"RSB",
"RSB",
"TEB",
469 "TEB",
"TEB",
"TEB",
"TEB"};
479 int irsb = 0, iteb = 0;
480 int l1bptrs_scan_idx;
481 for (ib = 0; ib <
nbands; ib++) {
484 f_corr = (f_cal_corr ==
NULL) ? 1.0
485 : f_cal_corr[ib][
l1rec->detnum][
l1rec->mside];
487 if (strcmp(bandType[ib],
"TEB") == 0) {
489 for (ip = 0; ip <
npix; ip++) {
491 l1rec->Ltir[ipb] = 0;
493 l1bptrs_scan_idx =
l1rec->detnum * 3200 + ip + extract_pixel_start;
495 if (l1bptrs[ib][l1bptrs_scan_idx] != -32767) {
496 l1rec->Ltir[ipb] = l1bptrs[ib][l1bptrs_scan_idx] / 10.0;
499 l1rec->Ltir[ipb] *= f_corr;
505 }
else if (strcmp(bandType[ib],
"CIR") == 0) {
507 for (ip = 0; ip <
npix; ip++) {
509 l1bptrs_scan_idx =
l1rec->detnum * 3200 + ip + extract_pixel_start;
511 if (l1bptrs[ib][l1bptrs_scan_idx] != -32767) {
512 l1rec->rho_cirrus[ip] = l1bptrs[ib][l1bptrs_scan_idx];
518 l1rec->rho_cirrus[ip] *= f_corr;
523 }
else if (strcmp(bandType[ib],
"RSB") == 0) {
528 for (ip = 0; ip <
npix; ip++) {
529 ipb = ip *
l1rec->l1file->nbands + irsb;
531 l1bptrs_scan_idx =
l1rec->detnum * 3200 + ip + extract_pixel_start;
533 if (l1bptrs[ib][l1bptrs_scan_idx] != -32767) {
534 l1rec->Lt[ipb] = l1bptrs[ib][l1bptrs_scan_idx];
540 l1rec->Lt[ipb] *= f_corr;
551 for (ip = 0; ip <
npix; ip++) {
562 size_t start[] = { 0, 0, 0 };
563 size_t count[] = { 1, 1, 1 };
567 if (!
file->geofile || !
file->geofile[0]) {
568 printf(
"-E- Geolocation file needs to be set\n");
576 if (
scan != prevScan) {
578 status = nc_get_var1_double(scanLineGrp, scanStartTimeId,
start, &scan_start_tai);
582 if (scan_start_tai > 0) {
584 lastvalidscan =
line;
585 l1rec->scantime = lastvalidtime;
587 l1rec->scantime = lastvalidtime + (time_interval * (
line - lastvalidscan));
604 for (ip = 0; ip <
npix; ip++) {
606 if (
l1rec->lat[ip] == latGeoFillValue)
607 l1rec->lat[ip] = latL2FillValue;
608 if (
l1rec->lon[ip] == lonGeoFillValue)
609 l1rec->lon[ip] = lonL2FillValue;
621 if (
file->geofile &&
file->geofile[0]) {
622 status = nc_close(geoFileId);