39 #define N_PRM_HEADERS 35
42 #define APH_MIN 0.0001
43 #define CARDER_FAIL -1
46 #define CFLAG_FAIL 0x0001
47 #define CFLAG_DEFAULT 0x0002
48 #define CFLAG_BLEND 0x0004
50 #define CFLAG_UNPKG 0x0010
51 #define CFLAG_PKG 0x0020
52 #define CFLAG_HIPKG 0x0040
53 #define CFLAG_GLOBAL 0x0080
55 #define CFLAG_LO412 0x0100
56 #define CFLAG_LO555 0x0200
57 #define CFLAG_CHLINC 0x0400
60 static int band1, band2, band3, band4;
65 static double a0[6], a1[6], a2[6], a3[6];
66 static double ga0[6], ga3[6];
67 static double upa0[6], upa3[6];
68 static double pa0[6], pa3[6];
69 static double hpa0[6], hpa1[6], hpa2[6], hpa3[6];
72 static double y_0, y_1;
73 static double c0, c1, c2, c3;
74 static double gc0, gc1, gc2, gc3;
75 static double upc0, upc1, upc2, upc3;
76 static double pc0, pc1, pc2, pc3;
77 static double hpc0, hpc1, hpc2, hpc3;
78 static double p0, p1, p2;
79 static double gp0, gp1, gp2;
80 static double upp0, upp1, upp2;
81 static double pp0, pp1, pp2;
82 static double hpp0, hpp1, hpp2;
83 static double d1, d2, d3;
84 static double low_412_thresh, low_555_thresh, chl_inconsistent_thresh;
85 static double aph_hi, aph_lo;
87 static double aphb1, aphb2, aphb3, aphb4, fmid;
88 static double tx[
NX + 1];
89 static double arr0, arr1;
93 static void get_params(
void);
94 static double get_aph(
int band,
double aph675);
101 double *atot,
double *aph,
102 double *adg,
double *bb,
double *bbp,
103 double *aphmPtr,
double *adgmPtr,
double *chlPtr,
106 double br15, br25, br35, exponent, laph;
107 double adg_def, aph_def, chl_def;
108 double abr15, abr25, abr35;
109 double x,
y, bb1, bb2, bb3, bb4;
111 double g12, g34, f0,
f1,
f2,
f3, f4, wph;
112 double funk_lo, funk_hi, flo, fhi;
114 double chl_mod, aph_mod, adg_mod;
115 double tchl_mod, taph_mod, tadg_mod;
118 double uptemp, gtemp, ptemp;
119 double sw0lo, sw1lo, sw2lo, sw3lo;
120 double dtsw1, dtsw2, dtsw3;
123 int i, xlo, xmid, xhi;
124 static double cpa1[6], cpa2[6];
125 static int firstCall = 1;
135 for (
i = 0;
i < 6;
i++) cpa1[
i] = a1[
i];
136 for (
i = 0;
i < 6;
i++) cpa2[
i] = a2[
i];
139 arr0 = log10(aph_lo);
140 arr1 = log10(aph_hi) - arr0;
141 for (
i = 0;
i <=
NX;
i++)
142 tx[
i] = pow(10.0, arr0 + arr1 * (
double)
i / (
double)
NX);
146 for (
i = 0;
i < 6;
i++) {
147 if (rrswl[
i] > 0.0) {
170 if (rrs[0] <= 0. || rrs[1] <= 0. || rrs[2] <= 0. || rrs[4] <= 0.) {
176 if (rrs[0] < low_412_thresh) {
179 if (rrs[4] < low_555_thresh) {
189 sw1lo = gtemp + (uptemp - gtemp) / 2.;
190 sw2lo = ptemp + (gtemp - ptemp) / 2.;
193 dtsw1 = sw0lo - sw1lo;
194 dtsw2 = sw1lo - sw2lo;
195 dtsw3 = sw2lo - sw3lo;
205 if (sst >= sw1lo && sst < sw0lo) {
206 weit = (sst - sw1lo) / dtsw1;
212 if (sst >= sw2lo && sst < sw1lo) {
213 weit = (sst - sw2lo) / dtsw2;
219 if (sst >= sw3lo && sst < sw2lo) {
220 weit = (sst - sw3lo) / dtsw3;
234 br15 = rrs[0] / rrs[4];
235 br25 = rrs[1] / rrs[4];
236 br35 = rrs[2] / rrs[4];
242 exponent =
MAX(
MIN(-1.147 - 1.963 * abr15 - 1.01 * abr15 * abr15 + 0.856 * abr25 + 1.702 * abr25*abr25, 10.0), -10.0);
243 adg_def = 1.5 * pow(10.0, exponent);
244 exponent =
MAX(
MIN(-0.919 + 1.037 * abr25 - 0.407 * abr25 * abr25 - 3.531 * abr35 + 1.579 * abr35*abr35, 10.0), -10.0);
245 aph_def =
MAX((pow(10.0, exponent) - 0.008) / 3.05,
APH_MIN);
249 x =
MAX(x0 + x1 * rrs[4], 0.0);
251 x =
MAX(x0 + x1 * 0.001, 0.0);
253 y =
MAX(y_0 + y_1 * rrs[1] / rrs[2], 0.0);
255 for (
i = 0;
i < 6;
i++) {
256 bbp[
i] =
x * pow(551. / rrswl[
i],
y);
257 bb [
i] = bbw[
i] + bbp[
i];
265 r12 = (rrs[band1] / bb1) / (rrs[band2] / bb2);
266 r34 = (rrs[band3] / bb3) / (rrs[band4] / bb4);
267 g12 = r12 * exp(-
s * (rrswl[band1] - 400.)) - exp(-
s * (rrswl[band2] - 400.));
268 g34 = r34 * exp(-
s * (rrswl[band3] - 400.)) - exp(-
s * (rrswl[band4] - 400.));
270 f0 = g12 * (aw[band4] + bb4 - r34 * (aw[band3] + bb3))
271 - g34 * (aw[band2] + bb2 - r12 * (aw[band1] + bb1));
273 f0 = g12 * (aw[band4] - r34 * aw[band3])
274 - g34 * (aw[band2] - r12 * aw[band1]);
283 for (it = 0; it <= 1; it++) {
428 exponent =
MAX(
MIN(c0 + c1 * abr35 + c2 * abr35 * abr35 + c3 * abr35 * abr35*abr35, 10.0), -10.0);
429 chl_def = pow(10.0, exponent);
435 aphb1 = get_aph(band1, tx[
NX]);
436 aphb2 = get_aph(band2, tx[
NX]);
437 aphb3 = get_aph(band3, tx[
NX]);
438 aphb4 = get_aph(band4, tx[
NX]);
439 funk_hi = f0 +
f1 * aphb1 +
f2 * aphb2 +
f3 * aphb3 + f4*aphb4;
441 aphb1 = get_aph(band1, tx[0]);
442 aphb2 = get_aph(band2, tx[0]);
443 aphb3 = get_aph(band3, tx[0]);
444 aphb4 = get_aph(band4, tx[0]);
445 funk_lo = f0 +
f1 * aphb1 +
f2 * aphb2 +
f3 * aphb3 + f4*aphb4;
447 if (funk_lo > 0.0 && funk_hi < 0.0) {
456 xmid = (xlo + xhi) / 2;
457 aphb1 = get_aph(band1, tx[xmid]);
458 aphb2 = get_aph(band2, tx[xmid]);
459 aphb3 = get_aph(band3, tx[xmid]);
460 aphb4 = get_aph(band4, tx[xmid]);
461 fmid = f0 +
f1 * aphb1 +
f2 * aphb2 +
f3 * aphb3 + f4*aphb4;
468 aphb1 = get_aph(band1, tx[xlo]);
469 aphb2 = get_aph(band2, tx[xlo]);
470 aphb3 = get_aph(band3, tx[xlo]);
471 aphb4 = get_aph(band4, tx[xlo]);
472 flo = f0 +
f1 * aphb1 +
f2 * aphb2 +
f3 * aphb3 + f4*aphb4;
474 aphb1 = get_aph(band1, tx[xhi]);
475 aphb2 = get_aph(band2, tx[xhi]);
476 aphb3 = get_aph(band3, tx[xhi]);
477 aphb4 = get_aph(band4, tx[xhi]);
478 fhi = f0 +
f1 * aphb1 +
f2 * aphb2 +
f3 * aphb3 + f4*aphb4;
481 taph_mod = tx[xlo] + (tx[xhi] - tx[xlo]) * flo / (flo - fhi);
485 wph = aw[band4] + get_aph(band4, taph_mod) + bb4
486 - r34 * (aw[band3] + get_aph(band3, taph_mod) + bb3);
488 wph = aw[band4] + get_aph(band4, taph_mod)
489 - r34 * (aw[band3] + get_aph(band3, taph_mod));
491 tadg_mod = wph / g34;
494 laph = log10(taph_mod);
495 exponent = p0 + p1 * laph + p2 * laph * laph;
496 tchl_mod = pow(10.0, exponent);
498 if (
fabs(log10(tchl_mod / chl_def)) > chl_inconsistent_thresh) {
503 if (taph_mod > aph_hi / 2.) {
504 wt = (tx[
NX] - taph_mod) / (tx[
NX] - aph_hi / 2.);
505 tchl_mod = wt * tchl_mod + (1.0 - wt) * chl_def;
506 tadg_mod = wt * tadg_mod + (1.0 - wt) * adg_def;
507 taph_mod = wt * taph_mod + (1.0 - wt) * aph_def;
526 for (
i = 0;
i < 6;
i++)
527 aph[
i] = get_aph(
i, aph_mod);
529 chl_mod = chl_mod * (1. - weit) + tchl_mod * weit;
530 adg_mod = adg_mod * (1. - weit) + tadg_mod * weit;
531 aph_mod = aph_mod * (1. - weit) + taph_mod * weit;
532 for (
i = 0;
i < 6;
i++)
533 aph[
i] = aph[
i]*(1. - weit) + get_aph(
i, aph_mod) * weit;
538 for (
i = 0;
i < 6;
i++) {
539 adg [
i] = adg_mod * exp(-
s * (rrswl[
i] - 400.0));
540 atot[
i] = aw[
i] + aph[
i] + adg[
i];
558 static void get_params(
void) {
560 char dummy[100], full_file[2048];
564 if ((tmp_str = getenv(
"OCDATAROOT")) ==
NULL) {
565 printf(
"OCDATAROOT environment variable is not defined.\n");
569 strcpy(full_file, tmp_str);
570 strcat(full_file,
"/common/carder.par");
571 fin = fopen(full_file,
"r");
573 printf(
"-E- %s line %d: error opening (%s) file", __FILE__, __LINE__, full_file);
577 printf(
"\nLoading Carder parameters from file %s\n", full_file);
580 fgets(dummy, 100 - 1, fin);
581 fscanf(fin,
"%d\n", &pk);
582 fscanf(fin,
"%lf %lf %lf %lf\n", &d1, &d2, &d3, &
delta);
583 fscanf(fin,
"%d %d %d %d\n", &band1, &band2, &band3, &band4);
584 for (
i = 0;
i < 6;
i++)
585 fscanf(fin,
"%d %lf %lf %lf %lf %lf %lf\n",
586 &lam[
i], &bbw[
i], &aw[
i], &ga0[
i], &a1[
i], &a2[
i], &ga3[
i]);
587 fscanf(fin,
"%lf\n", &
s);
588 fscanf(fin,
"%lf %lf\n", &x0, &x1);
589 fscanf(fin,
"%lf %lf\n", &y_0, &y_1);
590 fscanf(fin,
"%lf %lf %lf %lf\n", &gc0, &gc1, &gc2, &gc3);
591 fscanf(fin,
"%lf %lf %lf\n", &gp0, &gp1, &gp2);
592 fscanf(fin,
"%lf %lf %lf\n", &low_412_thresh, &low_555_thresh,
593 &chl_inconsistent_thresh);
594 fscanf(fin,
"%lf %lf\n", &aph_lo, &aph_hi);
595 fscanf(fin,
"%d\n", &bb_denom);
596 fscanf(fin,
"%lf %lf %lf %lf %lf %lf\n", &upa0[0], &upa0[1],
597 &upa0[2], &upa0[3], &upa0[4], &upa0[5]);
598 fscanf(fin,
"%lf %lf %lf %lf %lf %lf\n", &upa3[0], &upa3[1],
599 &upa3[2], &upa3[3], &upa3[4], &upa3[5]);
600 fscanf(fin,
"%lf %lf %lf %lf %lf %lf\n", &pa0[0], &pa0[1],
601 &pa0[2], &pa0[3], &pa0[4], &pa0[5]);
602 fscanf(fin,
"%lf %lf %lf %lf %lf %lf\n", &pa3[0], &pa3[1],
603 &pa3[2], &pa3[3], &pa3[4], &pa3[5]);
604 fscanf(fin,
"%lf %lf %lf %lf %lf %lf\n", &hpa0[0], &hpa0[1],
605 &hpa0[2], &hpa0[3], &hpa0[4], &hpa0[5]);
606 fscanf(fin,
"%lf %lf %lf %lf %lf %lf\n", &hpa1[0], &hpa1[1],
607 &hpa1[2], &hpa1[3], &hpa1[4], &hpa1[5]);
608 fscanf(fin,
"%lf %lf %lf %lf %lf %lf\n", &hpa2[0], &hpa2[1],
609 &hpa2[2], &hpa2[3], &hpa2[4], &hpa2[5]);
610 fscanf(fin,
"%lf %lf %lf %lf %lf %lf\n", &hpa3[0], &hpa3[1],
611 &hpa3[2], &hpa3[3], &hpa3[4], &hpa3[5]);
612 fscanf(fin,
"%lf %lf %lf %lf\n", &upc0, &upc1, &upc2, &upc3);
613 fscanf(fin,
"%lf %lf %lf %lf\n", &pc0, &pc1, &pc2, &pc3);
614 fscanf(fin,
"%lf %lf %lf %lf\n", &hpc0, &hpc1, &hpc2, &hpc3);
615 fscanf(fin,
"%lf %lf %lf\n", &upp0, &upp1, &upp2);
616 fscanf(fin,
"%lf %lf %lf\n", &pp0, &pp1, &pp2);
617 fscanf(fin,
"%lf %lf %lf\n", &hpp0, &hpp1, &hpp2);
627 static double get_aph(
int band,
double aph675) {
628 if (aph675 == -1.0) {
631 return a0[
band] * exp(a1[
band] * tanh(a2[
band] * log(aph675 / a3[
band]))) * aph675;
642 static float get_ndt(
float lon,
float lat) {
647 static int firstCall = 1;
649 typedef float map_t[
NDTNX];
665 int32 dims[H4_MAX_VAR_DIMS];
669 char name[H4_MAX_NC_NAME];
670 char sdsname[] =
"ndt";
671 char file[FILENAME_MAX];
679 if ((tmp_str = getenv(
"OCDATAROOT")) ==
NULL) {
680 printf(
"OCDATAROOT environment variable is not defined.\n");
684 strcat(
file,
"/common/ndt.hdf");
686 printf(
"\nLoading nitrate depletion temperature map from %s\n",
file);
689 sd_id = SDstart(
file, DFACC_RDONLY);
691 printf(
"-E- %s: Error opening file %s.\n",
697 sds_index = SDnametoindex(sd_id, sdsname);
698 if (sds_index == -1) {
699 printf(
"-E- %s: Error seeking %s SDS from %s.\n",
700 __FILE__, sdsname,
file);
705 sds_id = SDselect(sd_id, sds_index);
710 printf(
"-E- %s: Error reading SDS info for %s from %s.\n",
711 __FILE__, sdsname,
file);
715 printf(
"-E- %s: Dimension mis-match on %s array from %s.\n",
716 __FILE__, sdsname,
file);
718 printf(
" Reading %d x %d\n", dims[1], dims[0]);
729 printf(
"-E- %s: Error reading SDS %s from %s.\n",
730 __FILE__, sdsname,
file);
735 status = SDreadattr(sds_id, SDfindattr(sds_id,
"slope"), (VOIDP) &
slope);
737 printf(
"-E- %s: Error reading slope attribute for SDS %s from %s.\n",
738 __FILE__, sdsname,
file);
741 status = SDreadattr(sds_id, SDfindattr(sds_id,
"intercept"), (VOIDP) &
offset);
743 printf(
"-E- %s: Error reading intercept attribute for SDS %s from %s.\n",
744 __FILE__, sdsname,
file);
749 status = SDendaccess(sds_id);
775 static double *aph, *aphm;
776 static double *adg, *adgm;
777 static double *bbp, *bb;
780 static int CarderRecNum = -99;
785 atot = (
double*) malloc(
npix *
nbands *
sizeof (
double));
786 aph = (
double*) malloc(
npix *
nbands *
sizeof (
double));
787 adg = (
double*) malloc(
npix *
nbands *
sizeof (
double));
788 bb = (
double*) malloc(
npix *
nbands *
sizeof (
double));
789 bbp = (
double*) malloc(
npix *
nbands *
sizeof (
double));
790 chl = (
double*) malloc(
npix *
sizeof (
double));
791 aphm = (
double*) malloc(
npix *
sizeof (
double));
792 adgm = (
double*) malloc(
npix *
sizeof (
double));
800 if (
recnum == CarderRecNum)
810 static double *rrswl;
812 static int firstCall = 1;
832 l1str *
l1rec = l2rec->l1rec;
838 if ((rrswl = (
double *) calloc(
nbands,
sizeof (
double))) ==
NULL) {
839 printf(
"-E- : Error allocating memory to rrswl\n");
842 if ((indx = (
int *) calloc(
nbands,
sizeof (
int))) ==
NULL) {
843 printf(
"-E- : Error allocating memory to indx\n");
856 for (ib = 0; ib < 6; ib++) {
857 rrswl[ib] = (
double)
l1rec->l1file->fwave[indx[ib]];
858 printf(
"Carder wavelength %d is %f\n", ib, rrswl[ib]);
862 if ((rrs = (
double *) calloc(
nbands,
sizeof (
double))) ==
NULL) {
863 printf(
"-E- : Error allocating memory to rrs\n");
866 if ((aph1 = (
double *) calloc(
nbands,
sizeof (
double))) ==
NULL) {
867 printf(
"-E- : Error allocating memory to aph1\n");
870 if ((adg1 = (
double *) calloc(
nbands,
sizeof (
double))) ==
NULL) {
871 printf(
"-E- : Error allocating memory to adg1\n");
874 if ((atot1 = (
double *) calloc(
nbands,
sizeof (
double))) ==
NULL) {
875 printf(
"-E- : Error allocating memory to atot1\n");
878 if ((bb1 = (
double *) calloc(
nbands,
sizeof (
double))) ==
NULL) {
879 printf(
"-E- : Error allocating memory to bb1\n");
882 if ((bbp1 = (
double *) calloc(
nbands,
sizeof (
double))) ==
NULL) {
883 printf(
"-E- : Error allocating memory to bbp1\n");
887 for (ip = 0; ip <
l1rec->npix; ip++) {
892 for (ic = 0; ic < 6; ic++)
893 rrs[ic] = (
double) (l2rec->Rrs[ipb + indx[ic]]);
896 if (l2rec->sst !=
NULL && l2rec->sst[ip] > -2.0)
897 sst = l2rec->sst[ip];
899 sst =
l1rec->sstref[ip];
902 ndt = get_ndt(
l1rec->lon[ip],
l1rec->lat[ip]);
905 status =
carder_model(
nbands, rrs, rrswl, sst, ndt, atot1, aph1, adg1, bb1, bbp1, &aph_mod, &adg_mod, &chl_mod, &
flags);
909 for (ic = 0; ic < 6; ic++) {
910 atot[ipb + indx[ic]] = atot1[ic];
911 aph [ipb + indx[ic]] = aph1 [ic];
912 adg [ipb + indx[ic]] = adg1 [ic];
913 bb [ipb + indx[ic]] = bb1 [ic];
914 bbp [ipb + indx[ic]] = bbp1 [ic];
921 for (ic = 0; ic < 6; ic++) {
936 CarderRecNum =
l1rec->iscan;
958 int band =
p->prod_ix;
959 int prodID =
p->cat_ix;
965 for (ip = 0; ip < l2rec->l1rec->npix; ip++) {
967 ipb = ip * l2rec->l1rec->l1file->nbands +
band;
972 prod[ip] = (
float) chl[ip];
977 prod[ip] = (
float) adgm[ip];
979 prod[ip] = (
float) adg[ipb];
984 prod[ip] = (
float) aphm[ip];
986 prod[ip] = (
float) aph[ipb];
990 prod[ip] = (
float) atot[ipb];
994 prod[ip] = (
float) bbp[ipb];
998 prod[ip] = (
float) bb[ipb];
1002 printf(
"-E- %s line %d : erroneous product ID %d passed to get_carder().\n",
1003 __FILE__, __LINE__, prodID);
1014 int32_t ib, ip, ipb;
1015 int32_t
nbands = l2rec->l1rec->l1file->nbands;
1020 for (ip = 0; ip < l2rec->l1rec->npix; ip++)
for (ib = 0; ib <
nbands; ib++) {
1022 l2rec->a [ipb] = (
float) atot[ipb];
1023 l2rec->bb[ipb] = (
float) bb [ipb];
1035 static int firstCall = 1;
1043 float uptemp, gtemp, ptemp;
1044 float sw0lo, sw1lo, sw2lo, sw3lo;
1045 float dtsw1, dtsw2, dtsw3;
1060 if (rrs[2] <= 0. || rrs[4] <= 0.) {
1065 abr35 = log10(rrs[2] / rrs[4]);
1072 sw0lo = uptemp + 1.;
1073 sw1lo = gtemp + (uptemp - gtemp) / 2.;
1074 sw2lo = ptemp + (gtemp - ptemp) / 2.;
1077 dtsw1 = sw0lo - sw1lo;
1078 dtsw2 = sw1lo - sw2lo;
1079 dtsw3 = sw2lo - sw3lo;
1089 if (sst >= sw1lo && sst < sw0lo) {
1090 weit = (sst - sw1lo) / dtsw1;
1096 if (sst >= sw2lo && sst < sw1lo) {
1097 weit = (sst - sw2lo) / dtsw2;
1103 if (sst >= sw3lo && sst < sw2lo) {
1104 weit = (sst - sw3lo) / dtsw3;
1118 for (it = 0; it <= 1; it++) {
1151 exponent =
MAX(
MIN(c0 + c1 * abr35 + c2 * abr35 * abr35 + c3 * abr35 * abr35*abr35, 10.0), -10.0);
1152 tchl = pow(10.0, exponent);
1158 chl = chl * (1. - weit) + tchl * weit;
1170 static int firstCall = 1;
1180 l1str *
l1rec = l2rec->l1rec;
1185 if ((indx = (
int *) calloc(
nbands,
sizeof (
int))) ==
NULL) {
1186 printf(
"-E- : Error allocating memory to indx\n");
1199 for (ip = 0; ip <
l1rec->npix; ip++) {
1204 for (ic = 0; ic < 6; ic++)
1205 rrs[ic] = (l2rec->Rrs[ipb + indx[ic]]);
1208 if (l2rec->sst !=
NULL && l2rec->sst[ip] > -2.0)
1209 sst = l2rec->sst[ip];
1211 sst =
l1rec->sstref[ip];
1214 ndt = get_ndt(
l1rec->lon[ip],
l1rec->lat[ip]);