15 static float *Kd_spectral;
30 static int32_t *w =
NULL;
31 static float *
a =
NULL;
38 l1str *
l1rec = l2rec->l1rec;
43 if (w[0] < 0 || w[1] < 0) {
44 printf(
"Kd490_KD2: algorithm coefficients not provided for this sensor.\n");
49 if (ib1 < 0 || ib2 < 0) {
50 printf(
"Kd490_KD2: incompatible sensor wavelengths for this algorithm\n");
55 for (ip = 0; ip <
l1rec->npix; ip++) {
57 ipb =
l1rec->l1file->nbands*ip;
59 if (
l1rec->mask[ip] ||
60 l2rec->Rrs[ipb + ib1] <= 0.0 || l2rec->Rrs[ipb + ib2] <= 0.0) {
64 R = log10(l2rec->Rrs[ipb + ib1] / l2rec->Rrs[ipb + ib2]);
69 Kd[ip] =
a[0] + pow(10.0,
a[1] +
R * (
a[2] +
R * (
a[3] +
R * (
a[4] +
R *
a[5]))));
96 static int32_t *w =
NULL;
97 static float *
a =
NULL;
110 l1str *
l1rec = l2rec->l1rec;
111 uncertainty_t *uncertainty=
l1rec->uncertainty;
116 if (w[0] < 0 || w[1] < 0) {
117 printf(
"Kd490_KD2: algorithm coefficients not provided for this sensor.\n");
122 if (ib1 < 0 || ib2 < 0) {
123 printf(
"Kd490_KD2: incompatible sensor wavelengths for this algorithm\n");
129 for (ip = 0; ip <
l1rec->npix; ip++) {
131 ipb =
l1rec->l1file->nbands*ip;
133 Rrs1 = l2rec->Rrs[ipb + ib1];
134 Rrs2 = l2rec->Rrs[ipb + ib2];
137 uRrs1 = l2rec->Rrs[ipb + ib1];
138 uRrs2 = l2rec->Rrs[ipb + ib2];
141 if (
l1rec->mask[ip] || Rrs1 <= 0.0 || Rrs2 <= 0.0) {
146 R = log10(Rrs1 / Rrs2);
147 dRdR1 = 1./(log(10)*Rrs1);
148 dRdR2 = -1./(log(10)*Rrs2);
154 X =
a[1] +
R * (
a[2] +
R * (
a[3] +
R * (
a[4] +
R *
a[5])));
155 dXdR =
a[2] +
R * (2*
a[3] +
R*(3*
a[4] +
R*(4*
a[5])));
156 Kd =
a[0] + pow(10.0, X);
157 dKdX = log(10)*pow(10.,X);
158 dKdR1 = dKdX * dXdR * dRdR1;
159 dKdR2 = dKdX * dXdR * dRdR2;
160 uKd[ip] = sqrt( pow(dKdR1* uRrs1,2.) + pow(dKdR2*uRrs2,2.) );
187 static float a = 0.15645;
188 static float b = -1.5401;
189 static float Kw = 0.016;
191 static float maxval = 6.4;
193 l1str *
l1rec = l2rec->l1rec;
201 for (ip = 0; ip <
l1rec->npix; ip++) {
203 ipb =
l1rec->l1file->nbands*ip;
205 if (
l1rec->mask[ip]) {
208 }
else if (l2rec->nLw[ipb + 2] <= 0.0) {
210 }
else if (l2rec->nLw[ipb + 4] <= 0.0) {
213 k490[ip] =
a * pow(l2rec->nLw[ipb + 2] / l2rec->nLw[ipb + 4],
b) + Kw;
214 if (k490[ip] > maxval) {
240 static int32_t ib490;
241 static int32_t ib555;
243 static int firstCall = 1;
245 l1str *
l1rec = l2rec->l1rec;
259 printf(
"Kd_obpg: incompatible sensor wavelengths (no 555 or 565).\n");
264 printf(
"Kd_obpg: incompatible sensor wavelengths (no 490).\n");
271 for (ip = 0; ip <
l1rec->npix; ip++) {
273 ipb =
l1rec->l1file->nbands*ip;
275 if (
l1rec->mask[ip] ||
276 l2rec->nLw[ipb + ib490] <= 0.0 || l2rec->nLw[ipb + ib555] <= 0.0) {
281 k490[ip] =
a * pow(l2rec->nLw[ipb + ib490] / l2rec->nLw[ipb + ib555],
b);
326 static float Kw = 0.01660;
327 static float X = 0.077746;
328 static float e = 0.672846;
333 l1str *
l1rec = l2rec->l1rec;
335 for (ip = 0; ip <
l1rec->npix; ip++) {
337 chl = l2rec->chl[ip];
339 if (
l1rec->mask[ip] || chl <= 0.0) {
343 Kd[ip] = Kw + X * pow(chl, e);
383 static float *Kd490 =
NULL;
387 l1str *
l1rec = l2rec->l1rec;
390 if ((Kd490 = malloc(
l1rec->npix * sizeof (
float))) ==
NULL) {
391 printf(
"-E- %s: Error allocating space for %d records.\n", __FILE__,
l1rec->npix);
398 for (ip = 0; ip <
l1rec->npix; ip++) {
400 if (
l1rec->mask[ip] || Kd490[ip] <= 0.0) {
406 Kd[ip] = 0.0864 + 0.884 * Kd490[ip] - 0.00137 / Kd490[ip];
409 Kd[ip] = 0.0665 + 0.874 * Kd490[ip] - 0.00121 / Kd490[ip];
412 printf(
"-E- %s: Invalid depth for Kd(PAR) (1 or 2).\n", __FILE__);
445 static float *KdPAR =
NULL;
448 l1str *
l1rec = l2rec->l1rec;
452 if ((KdPAR = malloc(
l1rec->npix * sizeof (
float))) ==
NULL) {
453 printf(
"-E- %s: Error allocating space for %d records.\n", __FILE__,
l1rec->npix);
459 for (ip = 0; ip <
l1rec->npix; ip++) {
461 if (
l1rec->mask[ip] || KdPAR[ip] <= 1e-5) {
465 Zhl[ip] = 2.0 / KdPAR[ip];
497 void Kd532(l2str *l2rec,
int flag,
float k532[]) {
498 const float M532 = 0.68052;
499 const float KW490 = 0.0224;
500 const float KW532 = 0.05356;
502 static float maxval = 6.4;
507 l1str *
l1rec = l2rec->l1rec;
509 for (ip = 0; ip <
l1rec->npix; ip++) {
513 else if (k532[ip] >= maxval)
515 else if (
l1rec->mask[ip])
518 temp = M532 * (k532[ip] - KW490) + KW532;
520 k532[ip] = 1.0 / temp;
525 if (k532[ip] > maxval)
562 const float m1 = 4.259;
563 const float m2 = 0.520;
564 const float m3 = -10.800;
565 const float m4 = 0.265;
570 l1str *
l1rec = l2rec->l1rec;
573 printf(
"IOP-based Kd_lee product requires iop model selection (iop_opt). ");
574 printf(
"Using default model.\n");
579 for (ip = 0; ip <
l1rec->npix; ip++) {
583 if (
l1rec->mask[ip] || l2rec->a[ipb] <= 0.0 || l2rec->bb[ipb] <= 0.0 ) {
587 m0 = 1.0 + 0.005 *
l1rec->solz[ip];
588 Kd[ip] = m0 * l2rec->a[ipb]
589 + m1 * (1.0 - m2 * exp( m3 * l2rec->a[ipb])) * l2rec->bb[ipb]
590 * (1.0 - m4 * (
l1rec->sw_bb[ipb] / l2rec->bb[ipb]));
631 const float m1 = 4.259;
632 const float m2 = 0.520;
633 const float m3 = -10.800;
634 const float m4 = 0.265;
637 float Kd, dkda, dkdbb;
638 int ip, ipb, iopt_flag;
643 l1str *
l1rec = l2rec->l1rec;
646 printf(
"IOP-based Kd_lee product requires iop model selection (iop_opt). ");
647 printf(
"Using default model.\n");
652 switch (
input->iop_opt) {
660 printf(
"IOP-based uncertainty for Kd_lee requires support iop model (iop_opt). ");
661 printf(
"Kd uncertanties cannot be estimated, seetting to badval.\n");
667 for (ip = 0; ip <
l1rec->npix; ip++) {
676 if (
l1rec->mask[ip] || l2rec->a[ipb] <= 0.0 || l2rec->bb[ipb] <= 0.0 ) {
681 m0 = 1.0 + 0.005 *
l1rec->solz[ip];
682 Kd = m0 * l2rec->a[ipb]
683 + m1 * (1.0 - m2 * exp( m3 * l2rec->a[ipb])) * l2rec->bb[ipb]
684 * (1.0 - m4 * (
l1rec->sw_bb[ipb] / l2rec->bb[ipb]));
686 dkda = m0 + m1*(1. - m4*(
l1rec->sw_bb[ipb] / bb_unc[ipb]))*bb_unc[ipb]
687 * (-m2*m3*exp( m3 * a_unc[ipb]));
689 dkdbb = m1*(1. - m2*exp( m3 * a_unc[ipb]))*(1. - m4*(
l1rec->sw_bb[ipb] / l2rec->bb[ipb]));
691 uKd[ip] = sqrt (pow(dkda* a_unc[ipb],2.) + pow(dkdbb*bb_unc[ipb],2));
737 const float m1 = 4.18;
738 const float m2 = 0.52;
739 const float m3 = -10.80;
741 const float n1 = 7.41;
742 const float n2 = 0.13;
743 const float n3 = 4.36;
744 const float n4 = -0.0051;
745 const float n5 = 0.0094;
746 const float n6 = 1.78;
747 const float p = 1.14;
748 const float radCon =
M_PI / 180.0;
750 float m0, sasw, D0,
f,
lambda, Kd;
754 l1str *
l1rec = l2rec->l1rec;
757 printf(
"IOP-based Kd_lee product requires iop model selection (iop_opt). ");
758 printf(
"Using default model.\n");
763 for (ip = 0; ip <
l1rec->npix; ip++) {
767 sasw = asin(sin(radCon *
l1rec->solz[ip]) / 1.34);
768 f = n1 * (n2 - exp(-n3 * (
lambda / 490.))) - (n4 * (
lambda / 490.) + n5) * exp(n6 * (
l1rec->solz[ip] / 30.));
769 D0 = (
f / cos(sasw)) +
p * (1.0 -
f);
771 if (
l1rec->mask[ip] ||
772 l2rec->a[ipb] <= 0.0 || l2rec->bb[ipb] <= 0.0) {
776 m0 = 1.0 + 0.005 *
l1rec->solz[ip];
777 Kd = m0 * l2rec->a[ipb]
778 + m1 * (1.0 - m2 * exp(m3 * l2rec->a[ipb])) * l2rec->bb[ipb];
814 void Zphotic_lee(l2str *l2rec, l2prodstr *
p,
float Zp[]);
826 for (ip = 0; ip < l2rec->l1rec->npix; ip++) {
828 Kd[ip] = 1.0 / Zp[ip];
831 l2rec->l1rec->flags[ip] |=
PRODFAIL;
862 static int firstCall = 1;
864 static float alg_lambda[16], alg_inp[16];
866 static float *
b1, *w1, *w2, *
mean, *sd, b2;
867 static float *xnorm, *alayer;
868 static int32 nrrs, n_input, n_norm, n_nodes;
869 static int32 *bnd_ptr;
872 filehandle *
l1file = l2rec->l1rec->l1file;
886 if ((bnd_ptr = (int32 *) calloc(
l1file->nbands, sizeof (int32))) ==
NULL) {
887 printf(
"-E- : Error allocating memory to bnd_ptr in get_Kd\n");
890 if ((filedir = getenv(
"OCDATAROOT")) ==
NULL) {
891 printf(
"-E- %s, %d: OCDATAROOT env variable undefined.\n",
896 switch (
l1file->sensorID) {
898 strcat(
filename,
"/seawifs/iop/kd_jamet/seawifs_kd_jamet.dat");
901 strcat(
filename,
"/meris/iop/kd_jamet/meris_kd_jamet.dat");
905 "-E- %s, %d: Kd_jamet can only be generated for the SEAWIFS instrument\n",
910 printf(
"Loading Kd coefficient table %s\n",
filename);
913 fprintf(
stderr,
"-E- %s, %d: unable to open %s for reading\n",
921 while (com_ln == 1) {
923 fprintf(
stderr,
"-E- %s, %d: Error reading %s\n",
927 if (
line[0] !=
';') com_ln = 0;
929 if (sscanf(
line,
"%d", &nrrs) != 1) {
930 fprintf(
stderr,
"-E- %s, %d: Error reading %s\n",
934 for (
i = 0;
i < nrrs;
i++) {
935 fgets(
line, 800, fp);
936 sscanf(
line,
"%f", &alg_lambda[
i]);
939 n_norm = n_input + 1;
944 while (com_ln == 1) {
945 fgets(
line, 800, fp);
946 if (
line[0] !=
';') com_ln = 0;
948 sscanf(
line,
"%d", &n_nodes);
950 b1 = malloc(n_nodes *
sizeof (
float));
951 w1 = malloc(n_nodes * n_norm *
sizeof (
float));
952 w2 = malloc(n_nodes *
sizeof (
float));
953 mean = malloc(n_norm *
sizeof (
float));
954 sd = malloc(n_norm *
sizeof (
float));
955 xnorm = malloc(n_input *
sizeof (
float));
956 alayer = malloc(n_nodes *
sizeof (
float));
960 (xnorm ==
NULL) || (alayer ==
NULL)) {
961 fprintf(
stderr,
"-E- %s, %d: allocation of Kd weights failed\n",
969 while (com_ln == 1) {
970 fgets(
line, 800, fp);
971 if (
line[0] !=
';') com_ln = 0;
974 for (
i = 0;
i < n_nodes;
i++) {
975 fgets(
line, 800, fp);
976 sscanf(
line,
"%d %d %f", &poub, &poub, &
b1[
i]);
978 fgets(
line, 800, fp);
979 sscanf(
line,
"%d %d %f", &poub, &poub, &b2);
980 for (
j = 0;
j < n_input;
j++)
981 for (
i = 0;
i < n_nodes;
i++) {
982 fgets(
line, 800, fp);
983 sscanf(
line,
"%d %d %f", &poub, &poub, (w1 +
i + n_nodes *
j));
985 for (
j = 0;
j < n_nodes;
j++) {
986 fgets(
line, 800, fp);
987 sscanf(
line,
"%d %d %f", &poub, &poub, &w2[
j]);
993 while (com_ln == 1) {
994 fgets(
line, 800, fp);
995 if (
line[0] !=
';') com_ln = 0;
998 for (
i = 1;
i < n_norm;
i++) {
999 fgets(
line, 800, fp);
1003 while (com_ln == 1) {
1004 fgets(
line, 800, fp);
1005 if (
line[0] !=
';') com_ln = 0;
1007 sscanf(
line,
"%f", &sd[0]);
1008 for (
i = 1;
i < n_norm;
i++) {
1009 fgets(
line, 800, fp);
1010 sscanf(
line,
"%f", &sd[
i]);
1016 printf(
"Kd_jamet band assignment:\n");
1017 printf(
"Alg wave inst wave inst band\n");
1018 for (
i = 0;
i < nrrs;
i++) {
1020 printf(
"%7.2f %7.2f %3d\n", alg_lambda[
i],
1021 l1file->fwave[bnd_ptr[
i]], bnd_ptr[
i]);
1028 for (ip = 0; ip < l2rec->l1rec->npix; ip++) {
1029 ipb = ip *
l1file->nbands;
1034 if (l2rec->l1rec->mask[ip]) bad_prd = 1;
1047 for (
i = 0;
i < nrrs;
i++) {
1048 alg_inp[
i] = l2rec->Rrs[ ipb + bnd_ptr[
i] ];
1049 if (alg_inp[
i] <
BAD_FLT + 1) bad_prd = 1;
1055 l2rec->l1rec->flags[ip] |=
PRODFAIL;
1057 for (
i = 0;
i < n_input;
i++)
1058 xnorm[
i] = ((2. / 3.) *(alg_inp[
i] -
mean[
i])) / sd[
i];
1062 for (
i = 0;
i < n_nodes;
i++) {
1064 for (
j = 0;
j < n_input;
j++) {
1065 alayer[
i] += (xnorm[
j] * *(w1 +
i + n_nodes *
j));
1067 alayer[
i] = 1.715905 * (
float) tanh((2. / 3.) *
1071 for (
j = 0,
y = 0.;
j < n_nodes;
j++)
1072 y += (alayer[
j] * w2[
j]);
1076 y = 1.5 * (
y + b2) * sd[n_input] +
mean[n_input];
1077 *(Kd + ip) = (
float) pow(10., (
double)
y);
1104 const float factor = 0.7;
1106 static int ib443, ib490, ib620, ib665, ib645, ib469, ib859, ib865, firstCall = 1;
1109 if (firstCall == 1) {
1117 if (ib645 < 0 || ib469 < 0 || ib859 < 0) {
1128 if (ib443 < 0 || ib490 < 0 || ib620 < 0 || ib665 < 0 || ib865 < 0) {
1129 printf(
"Kd_rhos: incompatible sensor wavelengths for this algorithm\n");
1132 printf(
"Kd_rhos: Using the Meris band averaging for this product\n");
1140 for (ip = 0; ip < l2rec->l1rec->npix; ip++) {
1142 ipb = l2rec->l1rec->l1file->nbands*ip;
1145 if (l2rec->Rrs[ipb + ib645] <= 0.0 || l2rec->Rrs[ipb + ib469] <= 0.0 || l2rec->Rrs[ipb + ib859] <= 0.0) {
1147 l2rec->l1rec->flags[ip] |=
PRODFAIL;
1149 Kd[ip] = factor * (l2rec->l1rec->rhos[ipb + ib645] - l2rec->l1rec->rhos[ipb + ib859])
1150 / (l2rec->l1rec->rhos[ipb + ib469] - l2rec->l1rec->rhos[ipb + ib859]);
1154 for (ip = 0; ip < l2rec->l1rec->npix; ip++) {
1156 ipb = l2rec->l1rec->l1file->nbands*ip;
1159 if (l2rec->Rrs[ipb + ib665] <= 0.0 || l2rec->Rrs[ipb + ib620] <= 0.0 || l2rec->Rrs[ipb + ib443] <= 0.0 || l2rec->Rrs[ipb + ib490] <= 0.0 || l2rec->Rrs[ipb + ib865] <= 0.0) {
1161 l2rec->l1rec->flags[ip] |=
PRODFAIL;
1163 Kd[ip] = factor * ((l2rec->l1rec->rhos[ipb + ib620] + l2rec->l1rec->rhos[ipb + ib665]) / 2 - l2rec->l1rec->rhos[ipb + ib865])
1164 / ((l2rec->l1rec->rhos[ipb + ib443] + l2rec->l1rec->rhos[ipb + ib490]) / 2 - l2rec->l1rec->rhos[ipb + ib865]);
1188 l1str *
l1rec = l2rec->l1rec;
1192 int32 nwave =
l1rec->l1file->nbands;
1196 Kd_temp = (
float*) calloc(
npix,
sizeof (
float));
1198 Kd_spectral = (
float*)calloc(
npix*nwave,
sizeof (
float));
1200 for (iw=0;iw<nwave; iw++){
1203 switch (
p->cat_ix) {
1205 Kd_lee(l2rec, iw, Kd_temp);
1211 printf(
"Error: %s : 3d wavelength Kd not supported for model: %d\n", __FILE__,
p->cat_ix);
1216 for (ip=0;ip<
npix; ip++){
1218 Kd_spectral[ip*nwave +iw] = temp;
1230 static void extract_band_3d(
float *in_buf,
float *out_buf,
int numPixels,
int numBands) {
1231 float * out_ptr = out_buf;
1232 for (
int pix = 0; pix < numPixels; pix++) {
1233 float *in_ptr = in_buf + pix * numBands;
1234 for (
int band_3d = 0; band_3d <
input->nwavelengths_3d; band_3d++) {
1235 int band =
input->wavelength_3d_index[band_3d];
1236 *out_ptr = in_ptr[
band];
1246 void get_Kd(l2str *l2rec, l2prodstr *
p,
float prod[]) {
1253 switch (
p->cat_ix) {
1256 extract_band_3d(Kd_spectral, prod, l2rec->l1rec->npix, l2rec->l1rec->l1file->nbands);
1259 extract_band_3d(Kd_spectral, prod, l2rec->l1rec->npix, l2rec->l1rec->l1file->nbands);
1262 printf(
"Error: %s : 3d wavelenght extract not support for Kd model: %d\n", __FILE__,
p->cat_ix);
1269 switch (
p->cat_ix) {
1283 Kd_lee(l2rec,
p->prod_ix, prod);
1290 Kd532(l2rec,
p->prod_ix, prod);
1314 printf(
"Error: %s : Unknown product specifier: %d\n", __FILE__,
p->cat_ix);
1324 static int32_t *w =
NULL;
1325 static float *
a =
NULL;
1326 static int ib1 = -1;
1327 static int ib2 = -1;
1333 l1str *
l1rec = l2rec->l1rec;
1335 uncertainty_t *uncertainty=l2rec->l1rec->uncertainty;
1336 float *dRrs, *dkd490, *covariance_matrix, kd_temp,tmpderiv,*
Rrs;
1340 dRrs=uncertainty->dRrs;
1341 dkd490=&uncertainty->dkd490;
1342 if(
input->proc_uncertainty==2)
1343 covariance_matrix=uncertainty->covaraince_matrix;
1345 covariance_matrix=uncertainty->pixel_covariance;
1349 nbands=l2rec->l1rec->l1file->nbands;
1352 if (w[0] < 0 || w[1] < 0) {
1353 printf(
"Kd490_KD2: algorithm coefficients not provided for this sensor.\n");
1358 if (ib1 < 0 || ib2 < 0) {
1359 printf(
"Kd490_KD2: incompatible sensor wavelengths for this algorithm\n");
1364 ipb =
l1rec->l1file->nbands*ip;
1365 Rrs=&l2rec->Rrs[ipb];
1367 if (
l1rec->mask[ip] ||
1368 l2rec->Rrs[ipb + ib1] <= 0.0 || l2rec->Rrs[ipb + ib2] <= 0.0) {
1371 R = log10(l2rec->Rrs[ipb + ib1] / l2rec->Rrs[ipb + ib2]);
1375 kd_temp =
a[0] + pow(10.0,
a[1] +
R * (
a[2] +
R * (
a[3] +
R * (
a[4] +
R *
a[5]))));
1381 tmpderiv= (kd_temp-
a[0])* (
a[2]+2*
a[3]*
R+3*
a[4]*
R*
R+4*
a[5]*
R*
R*
R)*log(10);
1382 tmpderiv/=(log(10)*
Rrs[ib1]/
Rrs[ib2]);
1384 *dkd490=pow(dRrs[ib1]/
Rrs[ib2],2)+ pow(dRrs[ib2]*
Rrs[ib1]/(
Rrs[ib2]*
Rrs[ib2]),2);
1388 *dkd490=
fabs(tmpderiv)* sqrt(*dkd490);
1390 *dkd490=sqrt(*dkd490**dkd490+fit_unc*fit_unc*kd_temp*kd_temp)/kd_temp;