23 #include <gsl/gsl_errno.h>
24 #include <gsl/gsl_vector.h>
25 #include <gsl/gsl_blas.h>
26 #include <gsl/gsl_multifit_nlin.h>
39 static int32_t nbandsvis;
40 static float grd1 = 0.0949;
41 static float grd2 = 0.0794;
42 static float *aphstar;
43 static float *adgstar;
44 static float *bbpstar;
50 static int32_t pixday;
51 static float32 pixlon;
52 static float32 pixlat;
58 static int32_t GSMRecNum = -1;
85 static int firstCall = 1;
88 static int iseason = -1;
90 static int32_t ntwave = 6;
91 static float twave[6] = {412.0, 443.0, 490.0, 510.0, 555.0, 670.0};
92 static char season[4][7] = {
"Spring",
"Summer",
"Fall",
"Winter"};
94 static float tcoefs[5][4][6 + 2] = {
96 {0.02119, 0.02509, 0.01282, 0.00910, 0.00427, 0.02087, 0.01218, 0.0},
97 {0.02653, 0.02979, 0.01655, 0.01208, 0.00470, 0.02122, 0.01218, 0.0},
98 {0.02259, 0.02573, 0.01372, 0.01019, 0.00376, 0.02066, 0.01218, 0.0},
99 {0.02259, 0.02573, 0.01372, 0.01019, 0.00376, 0.02066, 0.01218, 0.0}
102 {0.02001, 0.02212, 0.01279, 0.00974, 0.00449, 0.01588, 0.01385, 0.0},
103 {0.03345, 0.03900, 0.02318, 0.01664, 0.00609, 0.02285, 0.01385, 0.0},
104 {0.02758, 0.03080, 0.01826, 0.01438, 0.00691, 0.02112, 0.01385, 0.0},
105 {0.02758, 0.03080, 0.01826, 0.01438, 0.00691, 0.02112, 0.01385, 0.0}
108 {0.02001, 0.02212, 0.01279, 0.00974, 0.00449, 0.01588, 0.01330, 0.0},
109 {0.03345, 0.03900, 0.02318, 0.01664, 0.00609, 0.02285, 0.01330, 0.0},
110 {0.02758, 0.03080, 0.01826, 0.01438, 0.00691, 0.02112, 0.01330, 0.0},
111 {0.02758, 0.03080, 0.01826, 0.01438, 0.00691, 0.02112, 0.01330, 0.0}
114 {0.07123, 0.08843, 0.06024, 0.04072, 0.01693, 0.03815, 0.01236, 0.0},
115 {0.07123, 0.08843, 0.06024, 0.04072, 0.01693, 0.03815, 0.01236, 0.0},
116 {0.07123, 0.08843, 0.06024, 0.04072, 0.01693, 0.03815, 0.01236, 0.0},
117 {0.07123, 0.08843, 0.06024, 0.04072, 0.01693, 0.03815, 0.01236, 0.0}
120 {0.11331, 0.14678, 0.09832, 0.06048, 0.01920, 0.04349, 0.01646, 1.0},
121 {0.11331, 0.14678, 0.09832, 0.06048, 0.01920, 0.04349, 0.01646, 1.0},
122 {0.11331, 0.14678, 0.09832, 0.06048, 0.01920, 0.04349, 0.01646, 1.0},
123 {0.11331, 0.14678, 0.09832, 0.06048, 0.01920, 0.04349, 0.01646, 1.0}
129 float *taphstar, adg_s, bbp_s;
131 if (firstCall == 1) {
133 if ((iwtab = (
int *) calloc(nbandsvis,
sizeof (
int))) ==
NULL) {
134 printf(
"-E- %s line %d : error allocating memory for iwtab in gsm:set_cb_model.\n",
138 if ((
interp = (
int *) calloc(nbandsvis,
sizeof (
int))) ==
NULL) {
139 printf(
"-E- %s line %d : error allocating memory for interp in gsm:set_cb_model.\n",
148 if (
day >= 79 &&
day < 172) iseason = 0;
149 else if (
day >= 172 &&
day < 265) iseason = 1;
150 else if (
day >= 265 &&
day < 355) iseason = 2;
153 printf(
"\nInitializing Chesapeake GSM model for %s\n", season[iseason]);
156 for (iw = 0; iw < nwave; iw++) {
157 iwtab[iw] =
windex(wave[iw], twave, ntwave);
158 if (fabsf(wave[iw] - twave[iwtab[iw]]) > 0.5) {
159 printf(
"\nGSM coefficients will be interpolated for %5.1f nm band.\n", wave[iw]);
168 if (lat < 37.0 && lon > (-(
lat + 152) / 2.5))
170 else if (
lat >= 37.0 &&
lon > ((
lat - 153.31) / 1.5385))
172 else if (
lon > -75.7)
182 taphstar = &tcoefs[iregion][iseason][0];
183 adg_s = tcoefs[iregion][iseason][ntwave + 0];
184 bbp_s = tcoefs[iregion][iseason][ntwave + 1];
185 for (iw = 0; iw < nwave; iw++) {
187 aphstar[iw] =
linterp(twave, taphstar, ntwave, wave[iw]);
189 aphstar[iw] = taphstar[iwtab[iw]];
190 adgstar[iw] = exp(-adg_s * (wave[iw] - 443.0));
191 bbpstar[iw] = pow((443.0 / wave[iw]), bbp_s);
215 int nwave = auxdata->
npnts;
221 for (iw = 0; iw < nwave; iw++) {
223 ac = aw [iw] + aphstar[iw] * par[0] + par[1] * adgstar[iw];
224 bb = bbw[iw] + par[2] * bbpstar[iw];
226 F = grd1 *
x + grd2 * pow(
x, 2);
228 auxdata->
yfit[iw] =
F;
230 merit += pow((auxdata->
y[iw] -
F), 2) * auxdata->
wgt[iw];
233 auxdata->
merit = merit;
244 double Rrs_fit[],
int16 *itercnt) {
245 static float tol = 1.e-6;
248 static double p0[] = {.1, .02, .0001};
249 static double d0[] = {5., 1.0, 0.01};
257 auxdata.
npnts = npts;
260 auxdata.
yfit = Rrs_fit;
280 *itercnt = auxdata.
niter;
301 l1str *
l1rec = l2rec->l1rec;
303 if ((
Rrs = (
double *) calloc(
l1rec->l1file->nbands, sizeof (
double))) ==
NULL) {
304 printf(
"-E- %s line %d : error allocating memory for Rrs in gsm:run_gsm_amb.\n",
308 if ((wts = (
double *) calloc(
l1rec->l1file->nbands, sizeof (
double))) ==
NULL) {
309 printf(
"-E- %s line %d : error allocating memory for wts in gsm:run_gsm_amb.\n",
313 if ((Rrs_fit = (
double *) calloc(
l1rec->l1file->nbands, sizeof (
double))) ==
NULL) {
314 printf(
"-E- %s line %d : error allocating memory for Rrs_fit in gsm:run_gsm_amb.\n",
320 for (ip = 0; ip <
l1rec->npix; ip++) {
329 if (
l1rec->mask[ip] == 0) {
332 pixlon =
l1rec->lon[ip];
333 pixlat =
l1rec->lat[ip];
337 pixday = (int32_t)
day;
339 for (iw = 0; iw < nbandsvis; iw++) {
341 Rrs[iw] = l2rec->Rrs[ip *
l1rec->l1file->nbands + iw];
342 Rrs[iw] =
Rrs[iw] / (0.52 + 1.7 *
Rrs[iw]);
376 GSMRecNum =
l1rec->iscan;
396 static int first = 1;
406 if ((dFdx = (
double *) calloc(nwave,
sizeof (
double))) ==
NULL) {
407 printf(
"-E- %s line %d : error allocating memory for dFdx in gsm:gsm_lm_f.\n",
411 if ((dxda = (
double *) calloc(nwave,
sizeof (
double))) ==
NULL) {
412 printf(
"-E- %s line %d : error allocating memory for dxda in gsm:gsm_lm_f.\n",
416 if ((dxdb = (
double *) calloc(nwave,
sizeof (
double))) ==
NULL) {
417 printf(
"-E- %s line %d : error allocating memory for dxdb in gsm:gsm_lm_f.\n",
428 for (iw = 0; iw < nwave; iw++) {
430 aphstar[iw] * gsl_vector_get(par, 0) + gsl_vector_get(par, 1) * adgstar[iw];
431 bb = bbw[iw] + gsl_vector_get(par, 2) * bbpstar[iw];
433 F = grd1 *
x + grd2 * pow(
x, 2);
435 dFdx[iw] = grd1 + 2 * grd2*
x;
436 dxda[iw] = -
x *
x / bb;
437 dxdb[iw] =
x / bb + dxda[iw];
439 gsl_vector_set(
f, iw, (
F -
y[iw]) /
sigma[iw]);
441 merit += pow((
F -
y[iw]) /
sigma[iw], 2);
467 for (iw = 0; iw < nwave; iw++) {
470 gsl_matrix_set(
J, iw, 0, dFdx[iw] * dxda[iw] * aphstar[iw] /
sigma[iw]);
471 gsl_matrix_set(
J, iw, 1, dFdx[iw] * dxda[iw] * adgstar[iw] /
sigma[iw]);
472 gsl_matrix_set(
J, iw, 2, dFdx[iw] * dxdb[iw] * bbpstar[iw] /
sigma[iw]);
479 gsl_vector *
f, gsl_matrix *
J) {
492 static int firstCall =
TRUE;
501 l1str *
l1rec = l2rec->l1rec;
503 const gsl_multifit_fdfsolver_type *T;
504 gsl_multifit_fdfsolver *
s;
506 static gsl_multifit_function_fdf
f;
507 double x_init[3] = {0.0, 0.0, 0.0};
508 gsl_vector_view
x = gsl_vector_view_array(x_init,
NPAR);
509 if ((
Rrs = (
double *) calloc(
l1rec->l1file->nbands, sizeof (
double))) ==
NULL) {
510 printf(
"-E- %s line %d : error allocating memory for Rrs in gsm:run_gsm_amb.\n",
514 if ((wts = (
double *) calloc(
l1rec->l1file->nbands, sizeof (
double))) ==
NULL) {
515 printf(
"-E- %s line %d : error allocating memory for wts in gsm:run_gsm_amb.\n",
519 if ((
sigma = (
double *) calloc(
l1rec->l1file->nbands, sizeof (
double))) ==
NULL) {
520 printf(
"-E- %s line %d : error allocating memory for sigma in gsm:run_gsm_amb.\n",
525 if (firstCall ==
TRUE) {
543 T = gsl_multifit_fdfsolver_lmsder;
544 s = gsl_multifit_fdfsolver_alloc(T, nbandsvis,
NPAR);
548 for (ip = 0; ip <
l1rec->npix; ip++) {
557 if (
l1rec->mask[ip] == 0) {
560 pixlon =
l1rec->lon[ip];
561 pixlat =
l1rec->lat[ip];
565 pixday = (int32_t)
day;
568 for (iw = 0; iw < nbandsvis; iw++) {
570 sigma[iw] = 1 / sqrt(wts[iw]);
571 Rrs[iw] = l2rec->Rrs[ip *
l1rec->l1file->nbands + iw];
572 Rrs[iw] =
Rrs[iw] / (0.52 + 1.7 *
Rrs[iw]);
590 gsl_multifit_fdfsolver_set(
s, &
f, &
x.vector);
594 status = gsl_multifit_fdfsolver_iterate(
s);
601 status = gsl_multifit_test_delta(
s->dx,
s->x, 1e-4, 1e-4);
607 if (itercnt ==
MAXITR || gsl_vector_get(
s->x, 0) <= 0.0) {
610 chl[ip] = gsl_vector_get(
s->x, 0);
611 adg[ip] = gsl_vector_get(
s->x, 1);
612 bbp[ip] = gsl_vector_get(
s->x, 2);
620 GSMRecNum =
l1rec->iscan;
621 gsl_multifit_fdfsolver_free(
s);
635 static int firstCall = 1;
636 static int last_npix;
638 l1str *
l1rec = l2rec->l1rec;
659 if ((aphstar = (
float *) calloc(
nbands,
sizeof (
float))) ==
NULL) {
660 printf(
"-E- %s line %d : error allocating memory for gsm.\n",
664 if ((adgstar = (
float *) calloc(
nbands,
sizeof (
double))) ==
NULL) {
665 printf(
"-E- %s line %d : error allocating memory for gsm.\n",
669 if ((bbpstar = (
float *) calloc(
nbands,
sizeof (
double))) ==
NULL) {
670 printf(
"-E- %s line %d : error allocating memory for gsm.\n",
675 printf(
"-E- %s line %d : error allocating memory for gsm.\n",
679 if ((aw = (
float *) calloc(
nbands,
sizeof (
float))) ==
NULL) {
680 printf(
"-E- %s line %d : error allocating memory for gsm.\n",
684 if ((bbw = (
float *) calloc(
nbands,
sizeof (
float))) ==
NULL) {
685 printf(
"-E- %s line %d : error allocating memory for gsm.\n",
689 if ((chl = (
double *) calloc(
l1rec->npix, sizeof (
double))) ==
NULL) {
690 printf(
"-E- %s line %d : error allocating memory for gsm.\n",
694 if ((adg = (
double *) calloc(
l1rec->npix, sizeof (
double))) ==
NULL) {
695 printf(
"-E- %s line %d : error allocating memory for gsm.\n",
699 if ((bbp = (
double *) calloc(
l1rec->npix, sizeof (
double))) ==
NULL) {
700 printf(
"-E- %s line %d : error allocating memory for gsm.\n",
705 printf(
"-E- %s line %d : error allocating memory for gsm.\n",
709 last_npix =
l1rec->npix;
712 coefset =
input->gsm_opt;
715 for (iw = 0; iw <
l1rec->l1file->nbands; iw++) {
724 adg_s =
input->gsm_adg_s;
725 bbp_s =
input->gsm_bbp_s;
726 taphw =
input->gsm_aphw;
727 taphs =
input->gsm_aphs;
729 for (taphn = 0; taphn < nbandsvis; taphn++)
730 if (taphw[taphn] < 0)
break;
731 for (iw = 0; iw < nbandsvis; iw++) {
733 adgstar[iw] = exp(-adg_s * (
lambda[iw] - 443.0));
734 bbpstar[iw] = pow((443.0 /
lambda[iw]), bbp_s);
742 for (iw = 0; iw < nbandsvis; iw++) {
747 for (iw = 0; iw < nbandsvis; iw++) {
748 aw [iw] =
l1rec->l1file->aw[iw];
749 bbw[iw] =
l1rec->l1file->bbw[iw];
755 if (
l1rec->npix > last_npix) {
757 if ((chl = (
double *) calloc(
l1rec->npix, sizeof (
double))) ==
NULL) {
758 printf(
"-E- %s line %d : error allocating memory for gsm.\n",
763 if ((adg = (
double *) calloc(
l1rec->npix, sizeof (
double))) ==
NULL) {
764 printf(
"-E- %s line %d : error allocating memory for gsm.\n",
769 if ((bbp = (
double *) calloc(
l1rec->npix, sizeof (
double))) ==
NULL) {
770 printf(
"-E- %s line %d : error allocating memory for gsm.\n",
776 printf(
"-E- %s line %d : error allocating memory for gsm.\n",
780 last_npix =
l1rec->npix;
783 switch (
input->gsm_fit) {
791 printf(
"%s Line %d: Unknown optimization method for GSM %d\n",
792 __FILE__, __LINE__,
input->gsm_fit);
803 void get_gsm(l2str *l2rec, l2prodstr *
p,
float prod[]) {
804 int prodID =
p->cat_ix;
805 int band =
p->prod_ix;
808 l1str *
l1rec = l2rec->l1rec;
813 for (ip = 0; ip <
l1rec->npix; ip++)
824 for (ip = 0; ip <
l1rec->npix; ip++) {
829 prod[ip] = (
float) chl[ip];
834 prod[ip] = (
float) adg[ip];
836 prod[ip] = (
float) adg[ip] * adgstar[iw];
841 prod[ip] = (
float) bbp[ip];
843 prod[ip] = (
float) bbp[ip] * bbpstar[iw];
847 prod[ip] = (
float) aphstar[iw] * chl[ip];
851 prod[ip] = (
float) aw[iw] + aphstar[iw] * chl[ip] + adg[ip] * adgstar[iw];
855 prod[ip] = (
float) bbw[iw] + bbp[ip] * bbpstar[iw];
859 printf(
"-E- %s line %d : erroneous product ID %d passed to gsm.\n",
860 __FILE__, __LINE__, prodID);
874 coefset =
input->gsm_opt;
875 if (!
gsm_ran(l2rec->l1rec->iscan))
885 int32_t
nbands = l2rec->l1rec->l1file->nbands;
887 coefset =
input->gsm_opt;
888 if (!
gsm_ran(l2rec->l1rec->iscan))
891 for (ip = 0; ip < l2rec->l1rec->npix; ip++)
892 for (ib = 0; ib <
nbands; ib++) {
894 l2rec->a [ipb] = (
float) aw[ib] + aphstar[ib] * chl[ip] + adg[ip] * adgstar[ib];
895 l2rec->bb[ipb] = (
float) bbw[ib] + bbp[ip] * bbpstar[ib];