22 #define TEMP_REF 273.15
26 #define SDNAME "Channel_"
30 static int32_t sd_id_g;
31 static int32_t spix = 0;
34 static float T_LOW = 185.;
35 static float T_HIGH = 370.;
37 static int pdbg1 = -1;
38 static int ldbg1 = -1;
53 const char xsatida[10];
62 sd_id = SDstart(
file->name, DFACC_RDONLY);
64 fprintf(
stderr,
"-E- %s line %d: SDstart(%s, %d) failed.\n",
65 __FILE__, __LINE__,
file->name, DFACC_RDONLY);
70 sds_id = SDselect(sd_id, SDnametoindex(sd_id, (
SDNAME"1")));
71 if (SDgetinfo(sds_id,
NULL, &
rank, dims, &
type, &numattr) == -1) {
72 fprintf(
stderr,
"-E- %s line %d: error getting dimension info.\n",
82 printf(
"-E- %s line %d: Error reading Number of scans attribute.\n",
87 if (
getHDFattr(sd_id,
"Orbit Number",
"", (VOIDP) &
file->orbit_number)
89 printf(
"-E- %s line %d: Error reading Orbit attribute.\n",
96 sd_id_g = SDstart(
file->geofile, DFACC_RDONLY);
97 if (sd_id_g ==
FAIL) {
98 printf(
"Error opening geolocation file.\n");
99 fprintf(
stderr,
"-E- %s line %d: SDstart(%s, %d) failed.\n",
100 __FILE__, __LINE__,
file->geofile, DFACC_RDONLY);
104 if (
getHDFattr(sd_id,
"Satellite",
"", (VOIDP) xsatida) != 0) {
105 printf(
"-E- %s line %d: Error reading Satellite attribute.\n",
110 if (
getHDFattr(sd_id,
"spatial_resolution",
"", (VOIDP) &
file->spatialResolution) != 0) {
111 printf(
"-W- %s line %d: Error reading spatial_resolution attribute.\n",
130 static int firstCall = 1;
131 static int firstScan = 1;
133 static int16_t *ch1 =
NULL;
134 static int16_t *ch2 =
NULL;
135 static int16_t *ch3 =
NULL;
137 static int16_t *ch5 =
NULL;
142 static float rayly[2];
143 static float aersol[2];
145 static int32_t ms = 0;
148 static int startOfMonth[2][12] = {
149 { 0, 31, 59, 90, 120, 151, 181, 212, 243,
151 { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305,
156 static double ch4_coeff[5] = {0.0351618, 1.24004, 0.979493, 8.6071114e-06,
158 static double ch5_coeff[5] = {0.0326272, 1.06256, 0.986256, 4.0256298e-06,
161 static char ingester[5];
164 int32_t
npix = (int32_t)
file->npix;
166 int32_t nbandsir = (int32_t)
file->nbandsir;
168 int32_t ich, iw, ip, ipb;
176 static float radinc[3];
177 static float radbas[3];
178 static float radinv[3][
NRADTAB];
179 static float teminc[3];
180 static float tembas[3];
181 static float teminv[3][
NRADTAB];
183 static int vbcksc[30];
184 static int vspace[50];
189 float64 sumbck[2][3];
190 float64 sumspc[2][5];
199 static int32_t *scantime;
204 int32_t irun, jrun, idif, iraw, jraw, ni;
208 float trad, ttem, tnlc;
219 for (ii = 0; ii < 50; ii++) {
227 for (ii = 0; ii < 30; ii++) {
235 if ((ch1 = (int16_t *) calloc(
npix,
sizeof (int16_t))) ==
NULL) {
236 printf(
"-E- %s line %d: Error allocating data space.\n",
242 printf(
"-E- %s line %d: Error reading Channel_1 Slope attribute.\n",
249 "-E- %s line %d: Error reading Channel_1 Intercept attribute.\n",
256 "-E- %s line %d: Error reading Channel_1 Scale_type attribute.\n",
260 if (strcmp(scaletype,
"y= Slope * x + Intercept;") != 0) {
261 printf(
"-E- %s line %d: Channel_1 Scale_type must be linear.\n",
266 if ((ch2 = (int16_t *) calloc(
npix,
sizeof (int16_t))) ==
NULL) {
267 printf(
"-E- %s line %d: Error allocating data space.\n",
273 printf(
"-E- %s line %d: Error reading Channel_2 Slope attribute.\n",
280 "-E- %s line %d: Error reading Channel_2 Intercept attribute.\n",
287 "-E- %s line %d: Error reading Channel_2 Scale_type attribute.\n",
291 if (strcmp(scaletype,
"y= Slope * x + Intercept;") != 0) {
292 printf(
"-E- %s line %d: Channel_2 Scale_type must be linear.\n",
297 if ((ch3 = (int16_t *) calloc(
npix,
sizeof (int16_t))) ==
NULL) {
298 printf(
"-E- %s line %d: Error allocating data space.\n",
304 printf(
"-E- %s line %d: Error reading Channel_3 Slope attribute.\n",
311 "-E- %s line %d: Error reading Channel_3 Intercept attribute.\n",
318 "-E- %s line %d: Error reading Channel_3 Scale_type attribute.\n",
322 if (strcmp(scaletype,
"y= Slope * x + Intercept;") != 0) {
323 printf(
"-E- %s line %d: Channel_3 Scale_type must be linear.\n",
328 if ((
ch4 = (int16_t *) calloc(
npix,
sizeof (int16_t))) ==
NULL) {
329 printf(
"-E- %s line %d: Error allocating data space.\n",
335 printf(
"-E- %s line %d: Error reading Channel_4 Slope attribute.\n",
342 "-E- %s line %d: Error reading Channel_4 Intercept attribute.\n",
349 "-E- %s line %d: Error reading Channel_4 Scale_type attribute.\n",
353 if (strcmp(scaletype,
"y= Slope * x + Intercept;") != 0) {
354 printf(
"-E- %s line %d: Channel_4 Scale_type must be linear.\n",
359 if ((ch5 = (int16_t *) calloc(
npix,
sizeof (int16_t))) ==
NULL) {
360 printf(
"-E- %s line %d: Error allocating data space.\n",
366 printf(
"-E- %s line %d: Error reading Channel_5 Slope attribute.\n",
373 "-E- %s line %d: Error reading Channel_5 Intercept attribute.\n",
380 "-E- %s line %d: Error reading Channel_5 Scale_type attribute.\n",
384 if (strcmp(scaletype,
"y= Slope * x + Intercept;") != 0) {
385 printf(
"-E- %s line %d: Channel_5 Scale_type must be linear.\n",
390 if (
getHDFattr(sd_id,
"start date",
"", (VOIDP) & startdate) != 0) {
391 printf(
"-E- %s line %d: Error reading start date attribute.\n",
396 sscanf(startdate,
"%04d-%02d-%02d", &
year, &month, &
day);
397 if (((
year % 400) == 0) || (((
year % 4) == 0) && ((
year % 100) != 0))) {
408 printf(
"-E- %s line %d: Error reading start time attribute.\n",
418 sscanf(
starttime,
"%02d:%02d:%02d.%03d", &hh, &mm, &ss, &ms);
420 if (
getHDFattr(sd_id,
"Satellite Name",
"", (VOIDP) satnam) != 0) {
421 printf(
"-E- %s line %d: Error reading Satellite Name attribute.\n",
426 if (
getHDFattr(sd_id,
"PRTEMP",
"", (VOIDP) & prtemp) != 0) {
427 printf(
"-E- %s line %d: Error reading PRTEMP attribute.\n",
441 if ((rawrec = (
RAW_CAL *) malloc(dims[0])) ==
NULL) {
442 printf(
"-E- %s line %d: Error allocating rawcal data space.\n",
447 strcat(tmpstr,
"Raw Running Calibration");
448 status =
rdSDS(sd_id, tmpstr, 0, 0, 0, 0, (VOIDP) rawrec);
450 printf(
"-E- %s line %d: Error reading %s.\n",
451 __FILE__, __LINE__, tmpstr);
456 strcat(tmpstr,
"Running Calibration");
457 if (
getDims(sd_id, tmpstr, dims) != 0) {
458 printf(
"-E- %s line %d: Error reading %s dim.\n",
459 __FILE__, __LINE__, tmpstr);
463 if ((runrec = (
RUN_CAL *) malloc(dims[0])) ==
NULL) {
464 printf(
"-E- %s line %d: Error allocating runcal data space.\n",
468 status =
rdSDS(sd_id, tmpstr, 0, 0, 0, 0, (VOIDP) runrec);
480 if (
getDims(sd_id,
"Scan start time", dims) != 0) {
481 printf(
"-E- %s line %d: Error reading Scan start time dim.\n",
485 if (dims[0] !=
l1rec->l1file->nscan) {
487 "-E- %s line %d: Error: Number of Scan start times (%d) must match Number of Scans (%d).\n",
488 __FILE__, __LINE__, dims[0],
l1rec->l1file->nscan);
491 if ((scantime = (int32_t *) malloc(dims[0] *
sizeof (int32_t))) ==
NULL) {
492 printf(
"-E- %s line %d: Error allocating scantime data space.\n",
496 status =
rdSDS(sd_id,
"Scan start time", 0, 0, 0, 0, (VOIDP) scantime);
498 printf(
"-E- %s line %d: Error reading scan start time\n",
512 switch (
file->subsensorID) {
514 printf(
"I Applying NOAA-7 visible degradation.\n");
516 + 0.0050 * pow((
float)
year + ((
float)
jday / (
float) LY) - 1981.5, 2));
518 + 0.0050 * pow((
float)
year + ((
float)
jday / (
float) LY) - 1981.5, 2));
520 + 0.0110 * pow((
float)
year + ((
float)
jday / (
float) LY) - 1981.5, 2));
522 + 0.0110 * pow((
float)
year + ((
float)
jday / (
float) LY) - 1981.5, 2));
525 printf(
"I Applying NOAA-9 visible degradation.\n");
526 m[0] = m[0] / (0.953 - 0.051 * ((
float)
year + ((
float)
jday / (
float) LY) - 1985.0));
528 m[1] = m[1] / (0.866 - 0.026 * ((
float)
year + ((
float)
jday / (
float) LY) - 1985.0));
532 printf(
"I Applying NOAA-11 visible degradation.\n");
533 m[0] = m[0] / (0.797 - 0.010 * ((
float)
year + ((
float)
jday / (
float) LY) - 1989.0));
535 m[1] = m[1] / (0.683 - 0.020 * ((
float)
year + ((
float)
jday / (
float) LY) - 1989.0));
540 RelDay = ((
year - 1994) * 365 + (
jday - 364));
541 printf(
"I Applying NOAA-14 visible degradation.\n");
546 m[0] = 0.0000232 * (
float) RelDay + 0.109;
548 m[1] = 0.0000373 * (
float) RelDay + 0.129;
552 printf(
"I No visible degradation available for NOAA-%2.0d.\n",
565 for (iw = 0; iw <= 2; iw++) {
576 radinv[iw][0] = T_LOW;
580 for (ip = 1; ip <
NRADTAB; ip++) {
581 ttem = pow(10., radbas[iw] + radinc[iw] * (
float) (ip));
587 teminc[iw] = (T_HIGH - T_LOW) / (
float) (
NRADTAB - 1);
598 for (ip = 1; ip <
NRADTAB; ip++) {
599 ttem = tembas[iw] + (teminc[iw] * (
float) (ip));
616 if (
scan > 0 && (scantime[
scan] < scantime[
scan - 1])) {
629 READ_SDS_ID(sd_id_g,
"Longitude",
l1rec->lon,
scan, spix, 0, 0, 1,
npix, 1,
631 READ_SDS_ID(sd_id_g,
"Latitude",
l1rec->lat,
scan, spix, 0, 0, 1,
npix, 1,
640 for (ip = 0; ip <
npix; ip++) {
642 l1rec->pixnum[ip] = spix + ip;
644 if (
l1rec->lon[ip] < -181.0 ||
l1rec->lon[ip] > 181.0
645 ||
l1rec->lat[ip] < -91.0 ||
l1rec->lat[ip] > 91.0)
646 l1rec->navfail[ip] = 1;
650 READ_SDS_ID(sd_id,
SDNAME"1", ch1,
scan, spix, 0, 0, 1,
npix, 1, 1);
651 READ_SDS_ID(sd_id,
SDNAME"2", ch2,
scan, spix, 0, 0, 1,
npix, 1, 1);
652 READ_SDS_ID(sd_id,
SDNAME"3", ch3,
scan, spix, 0, 0, 1,
npix, 1, 1);
653 READ_SDS_ID(sd_id,
SDNAME"4",
ch4,
scan, spix, 0, 0, 1,
npix, 1, 1);
654 READ_SDS_ID(sd_id,
SDNAME"5", ch5,
scan, spix, 0, 0, 1,
npix, 1, 1);
676 for (ip = 0; ip < runrec->numcal; ip++) {
677 if (
abs((
int)(runrec->runcal[ip].cenlin - ascan)) < idif) {
678 idif =
abs((
int)(runrec->runcal[ip].cenlin - ascan));
683 if (irun == -1 || idif > runrec->intrvl) {
684 printf(
"-W- %s line %d: Hey, I can't find the RUNCAL entry!\n",
686 printf(
"-W- scan: %f; first center scan: %f; last: %f", ascan,
687 runrec->runcal[0].cenlin,
688 runrec->runcal[runrec->numcal - 1].cenlin);
690 if (ascan < runrec->runcal[1].cenlin) {
693 irun = runrec->numcal - 1;
697 if (ascan > runrec->runcal[irun].cenlin) {
698 if (irun < runrec->numcal - 1) {
713 if (runrec->runcal[irun].cenlin != runrec->runcal[jrun].cenlin) {
714 percnt = (ascan - runrec->runcal[irun].cenlin)
715 / (runrec->runcal[jrun].cenlin - runrec->runcal[irun].cenlin);
718 }
else if (percnt > 1.0) {
728 for (ii = 1; ii <= 30; ii++) {
731 for (jj = 0; jj < 2; jj++) {
732 sumbck[jj][iw - 1] = 0.0;
735 sumbck[0][iw - 1] += rawrec->rawcal[iraw].bckscn[0][vbcksc[ii - 1]]
737 + rawrec->rawcal[jraw].bckscn[0][vbcksc[ii - 1]] * (percnt);
738 sumbck[1][iw - 1] += rawrec->rawcal[iraw].bckscn[1][vbcksc[ii - 1]]
740 + rawrec->rawcal[jraw].bckscn[1][vbcksc[ii - 1]] * (percnt);
742 for (iw = 0; iw < 3; iw++) {
743 if (sumbck[0][iw] > 0.0) {
744 avgbck[iw] = sumbck[1][iw] / sumbck[0][iw];
751 for (ii = 1; ii <= 50; ii++) {
754 for (jj = 0; jj < 2; jj++) {
755 sumspc[jj][iw - 1] = 0.0;
758 sumspc[0][iw - 1] += rawrec->rawcal[iraw].space[0][vspace[ii - 1]]
760 + rawrec->rawcal[jraw].space[0][vspace[ii - 1]] * (percnt);
761 sumspc[1][iw - 1] += rawrec->rawcal[iraw].space[1][vspace[ii - 1]]
763 + rawrec->rawcal[jraw].space[1][vspace[ii - 1]] * (percnt);
765 for (iw = 0; iw < 3; iw++) {
766 if (sumspc[0][iw + 2] > 0.0) {
767 avgspc[iw] = sumspc[1][iw + 2] / sumspc[0][iw + 2];
774 prtemp = (1.0 - percnt) * runrec->runcal[irun].prtemp
775 + (percnt) * runrec->runcal[jrun].prtemp;
777 for (iw = 0; iw < 3; iw++) {
780 if (ttem < tembas[iw])
782 ai = (ttem - tembas[iw]) / teminc[iw];
789 radprt[iw] = (1.0 - ai) * teminv[iw][ni] + ai * teminv[iw][ni + 1];
793 switch (
file->subsensorID) {
848 for (iw = 0; iw <
nbands + 1; iw++) {
862 for (ip = 0; ip <
npix; ip++) {
865 l1rec->Lt[ipb] = 0.0;
868 if (
data[ip] >= 32000) {
874 l1rec->Lt[ipb] = 1000.0;
885 l1rec->Lt[ipb] = 1000.0;
888 &
l1rec->delphi[ip], rayly, aersol,
889 &
l1rec->glint_coef[ip]);
891 trad = (
data[ip] * m[iw]) +
b[iw];
894 if (aersol[iw] != 0.0) {
899 l1rec->Lt[ipb] = trad;
905 for (iw = 0; iw < nbandsir; iw++) {
919 for (ip = 0; ip <
npix; ip++) {
922 l1rec->Ltir[ipb] = 0.0;
935 if (
data[ip] >= 32000) {
941 l1rec->Lt[ipb] = 1000.0;
950 if (avgbck[iw] != avgspc[iw]) {
960 if (ip == pdbg1 &&
scan == ldbg1) {
961 printf(
" ch4_coeffs=%f %f %f %f %f\n",
962 ch4_coeff[0], ch4_coeff[1],
963 ch4_coeff[2], ch4_coeff[3],
965 printf(
" T_inst, prtemp = %f \n", prtemp);
966 printf(
" R_ICT, radprt = %f \n",
968 printf(
" C_S, avgspc = %f \n", avgspc[iw]);
969 printf(
" C_BB, avgbck = %f \n", avgbck[iw]);
970 printf(
" C, data = %d \n",
data[ip]);
972 trad = ch4_coeff[0] * (prtemp - 288.) + ch4_coeff[1]
973 + ((((ch4_coeff[2] * radprt[iw]) - (ch4_coeff[3]
974 * (pow(avgspc[iw] - avgbck[iw], 2.0))))
975 / (avgspc[iw] - avgbck[iw])) * (avgspc[iw] -
data[ip]))
976 + ch4_coeff[4] * (pow(avgspc[iw] -
data[ip], 2.0));
977 }
else if (iw == 2) {
979 if (ip == pdbg1 &&
scan == ldbg1) {
980 printf(
" ch5_coeffs=%f %f %f %f %f\n",
981 ch5_coeff[0], ch5_coeff[1],
982 ch5_coeff[2], ch5_coeff[3],
984 printf(
" T_inst, prtemp = %f \n", prtemp);
985 printf(
" R_ICT, radprt = %f \n",
987 printf(
" C_S, avgspc = %f \n", avgspc[iw]);
988 printf(
" C_BB, avgbck = %f \n", avgbck[iw]);
989 printf(
" C, data = %d \n",
data[ip]);
991 trad = ch5_coeff[0] * (prtemp - 288.) + ch5_coeff[1]
992 + ((((ch5_coeff[2] * radprt[iw]) - (ch5_coeff[3]
993 * (pow(avgspc[iw] - avgbck[iw], 2.0))))
994 / (avgspc[iw] - avgbck[iw])) * (avgspc[iw] -
data[ip]))
995 + ch5_coeff[4] * (pow(avgspc[iw] -
data[ip], 2.0));
999 trad = radprt[iw] * (avgspc[iw] -
data[ip])
1000 / (avgspc[iw] - avgbck[iw])
1001 + rspc[iw] * (avgbck[iw] -
data[ip])
1002 / (avgbck[iw] - avgspc[iw]);
1005 switch (
file->subsensorID) {
1007 tnlc = 5.7843 - 1.0754e-1 * trad + 4.8042e-4 * pow(trad, 2);
1010 tnlc = 5.24 + (.88643 - 1.) * trad + 6.033e-4 * pow(trad, 2);
1013 tnlc = 5.76 + (.88428 - 1.) * trad + 5.882e-4 * pow(trad, 2);
1016 tnlc = 7.21 + (.8412 - 1.) * trad + 8.739e-4 * pow(trad, 2);
1019 tnlc = 5.11 + (.88929 - 1.) * trad + 5.968e-4 * pow(trad, 2);
1022 tnlc = 3.72 + (.92378 - 1.) * trad
1023 + 3.822e-4 * pow(trad, 2);
1026 tnlc = 4.76 + (-0.0932) * trad + 4.524e-4 * pow(trad, 2);
1029 tnlc = 2.96 + (-0.05411) * trad + 2.4532e-4 * pow(trad, 2);
1032 tnlc = 8.22 + (-0.15795) * trad + 7.5579e-4 * pow(trad, 2);
1035 tnlc = 5.82 + (-0.11069) * trad + 5.2337e-4 * pow(trad, 2);
1038 tnlc = 5.70 + (-0.11187) * trad + 5.4668e-4 * pow(trad, 2);
1044 }
else if (iw == 2) {
1046 switch (
file->subsensorID) {
1048 tnlc = 4.4035 - 6.9038e-2 * trad + 2.5741e-4 * pow(trad, 2);
1051 tnlc = 2.42 + (.95311 - 1.) * trad + 2.198e-4 * pow(trad, 2);
1054 tnlc = 5.76 + (.88428 - 1.) * trad + 5.882e-4 * pow(trad, 2);
1057 tnlc = 2.92 + (.94598 - 1.) * trad + 2.504e-4 * pow(trad, 2);
1060 tnlc = 1.91 + (.96299 - 1.) * trad + 1.775e-4 * pow(trad, 2);
1063 tnlc = 2.00 + (.96194 - 1.) * trad + 1.742e-4 * pow(trad, 2);
1066 tnlc = 3.83 + (-0.0659) * trad + 2.811e-4 * pow(trad, 2);
1069 tnlc = 2.25 + (-0.03665) * trad + 1.4854e-4 * pow(trad, 2);
1072 tnlc = 4.31 + (-0.07318) * trad + 3.0976e-4 * pow(trad, 2);
1075 tnlc = 2.67 + (-0.04360) * trad + 1.7715e-4 * pow(trad, 2);
1078 tnlc = 3.58 + (-0.05991) * trad + 2.4985e-4 * pow(trad, 2);
1087 if (ip == pdbg1 &&
scan == ldbg1) {
1088 printf(
" ch %d trad = %f\n", iw + 3, trad);
1089 printf(
" newavhrrcal = %d\n",
1091 printf(
" xsatid = %d NO16=%d\n",
1097 if (radinc[iw] != 0.0)
1098 ai = (log10(trad) - radbas[iw]) / radinc[iw];
1107 ttem = (1.0 - ai) * radinv[iw][ni] + ai * radinv[iw][ni + 1];
1108 if (ip == pdbg1 &&
scan == ldbg1) {
1109 printf(
" ch %d ttem = %f\n", iw + 3, ttem);
1112 == 1 &&
file->subsensorID ==
NO16) {
1123 tcor = -6.9176245 + 0.038554339 * ttem - 4.7661371e-05 * pow(ttem, 2);
1128 l1rec->Bt[ipb - 1] =
l1rec->Bt[ipb - 1] + tcor;
1129 if (ip == pdbg1 &&
scan == ldbg1) {
1130 printf(
" real ch = %d, ttem = %f, tcor = %f\n", iw + 3 - 1, ttem, tcor);
1133 if (ip == pdbg1 &&
scan == ldbg1) {
1134 printf(
" ch = %d, ttem = %f, tcor = %f\n", iw + 3, ttem, tcor);
1138 l1rec->Bt[ipb] = ttem;
1150 l1rec->detnum = (int32_t) detnum;
1159 if ((sd_id_g != sd_id) && SDend(sd_id_g)) {
1160 fprintf(
stderr,
"-E- %s line %d: SDend(%d) failed for file, %s.\n",
1161 __FILE__, __LINE__, sd_id,
file->geofile);
1165 fprintf(
stderr,
"-E- %s line %d: SDend(%d) failed for file, %s.\n",
1166 __FILE__, __LINE__, sd_id,
file->name);
1207 if (strcmp(satname,
"NOA6") == 0)
1209 else if (strcmp(satname,
"NOA7") == 0)
1211 else if (strcmp(satname,
"NOA8") == 0)
1213 else if (strcmp(satname,
"NOA9") == 0)
1215 else if (strcmp(satname,
"NO10") == 0)
1217 else if (strcmp(satname,
"NO11") == 0)
1219 else if (strcmp(satname,
"NO12") == 0)
1221 else if (strcmp(satname,
"NO14") == 0)
1223 else if (strcmp(satname,
"NO15") == 0)
1225 else if (strcmp(satname,
"NO16") == 0)
1227 else if (strcmp(satname,
"NO17") == 0)
1229 else if (strcmp(satname,
"NO18") == 0)
1231 else if (strcmp(satname,
"NO19") == 0)