Go to the documentation of this file.
29 static int32_t *w =
NULL;
30 static float *
a =
NULL;
37 l1str *
l1rec = l2rec->l1rec;
42 if (w[0] < 0 || w[1] < 0) {
43 printf(
"Kd490_KD2: algorithm coefficients not provided for this sensor.\n");
48 if (ib1 < 0 || ib2 < 0) {
49 printf(
"Kd490_KD2: incompatible sensor wavelengths for this algorithm\n");
54 for (ip = 0; ip <
l1rec->npix; ip++) {
56 ipb =
l1rec->l1file->nbands*ip;
58 if (
l1rec->mask[ip] ||
59 l2rec->Rrs[ipb + ib1] <= 0.0 || l2rec->Rrs[ipb + ib2] <= 0.0) {
63 R = log10(l2rec->Rrs[ipb + ib1] / l2rec->Rrs[ipb + ib2]);
68 Kd[ip] =
a[0] + pow(10.0,
a[1] +
R * (
a[2] +
R * (
a[3] +
R * (
a[4] +
R *
a[5]))));
95 static float a = 0.15645;
96 static float b = -1.5401;
97 static float Kw = 0.016;
99 static float maxval = 6.4;
101 l1str *
l1rec = l2rec->l1rec;
109 for (ip = 0; ip <
l1rec->npix; ip++) {
111 ipb =
l1rec->l1file->nbands*ip;
113 if (
l1rec->mask[ip]) {
116 }
else if (l2rec->nLw[ipb + 2] <= 0.0) {
118 }
else if (l2rec->nLw[ipb + 4] <= 0.0) {
121 k490[ip] =
a * pow(l2rec->nLw[ipb + 2] / l2rec->nLw[ipb + 4],
b) + Kw;
122 if (k490[ip] > maxval) {
148 static int32_t ib490;
149 static int32_t ib555;
151 static int firstCall = 1;
153 l1str *
l1rec = l2rec->l1rec;
167 printf(
"Kd_obpg: incompatible sensor wavelengths (no 555 or 565).\n");
172 printf(
"Kd_obpg: incompatible sensor wavelengths (no 490).\n");
179 for (ip = 0; ip <
l1rec->npix; ip++) {
181 ipb =
l1rec->l1file->nbands*ip;
183 if (
l1rec->mask[ip] ||
184 l2rec->nLw[ipb + ib490] <= 0.0 || l2rec->nLw[ipb + ib555] <= 0.0) {
189 k490[ip] =
a * pow(l2rec->nLw[ipb + ib490] / l2rec->nLw[ipb + ib555],
b);
234 static float Kw = 0.01660;
235 static float X = 0.077746;
236 static float e = 0.672846;
241 l1str *
l1rec = l2rec->l1rec;
243 for (ip = 0; ip <
l1rec->npix; ip++) {
245 chl = l2rec->chl[ip];
247 if (
l1rec->mask[ip] || chl <= 0.0) {
251 Kd[ip] = Kw + X * pow(chl, e);
291 static float *Kd490 =
NULL;
295 l1str *
l1rec = l2rec->l1rec;
298 if ((Kd490 = malloc(
l1rec->npix * sizeof (
float))) ==
NULL) {
299 printf(
"-E- %s: Error allocating space for %d records.\n", __FILE__,
l1rec->npix);
306 for (ip = 0; ip <
l1rec->npix; ip++) {
308 if (
l1rec->mask[ip] || Kd490[ip] <= 0.0) {
314 Kd[ip] = 0.0864 + 0.884 * Kd490[ip] - 0.00137 / Kd490[ip];
317 Kd[ip] = 0.0665 + 0.874 * Kd490[ip] - 0.00121 / Kd490[ip];
320 printf(
"-E- %s: Invalid depth for Kd(PAR) (1 or 2).\n", __FILE__);
353 static float *KdPAR =
NULL;
356 l1str *
l1rec = l2rec->l1rec;
360 if ((KdPAR = malloc(
l1rec->npix * sizeof (
float))) ==
NULL) {
361 printf(
"-E- %s: Error allocating space for %d records.\n", __FILE__,
l1rec->npix);
367 for (ip = 0; ip <
l1rec->npix; ip++) {
369 if (
l1rec->mask[ip] || KdPAR[ip] <= 1e-5) {
373 Zhl[ip] = 2.0 / KdPAR[ip];
405 void Kd532(l2str *l2rec,
int flag,
float k532[]) {
406 const float M532 = 0.68052;
407 const float KW490 = 0.0224;
408 const float KW532 = 0.05356;
410 static float maxval = 6.4;
415 l1str *
l1rec = l2rec->l1rec;
417 for (ip = 0; ip <
l1rec->npix; ip++) {
421 else if (k532[ip] >= maxval)
423 else if (
l1rec->mask[ip])
426 temp = M532 * (k532[ip] - KW490) + KW532;
428 k532[ip] = 1.0 / temp;
433 if (k532[ip] > maxval)
470 const float m1 = 4.259;
471 const float m2 = 0.520;
472 const float m3 = -10.800;
473 const float m4 = 0.265;
478 l1str *
l1rec = l2rec->l1rec;
481 printf(
"IOP-based Kd_lee product requires iop model selection (iop_opt). ");
482 printf(
"Using default model.\n");
487 for (ip = 0; ip <
l1rec->npix; ip++) {
491 if (
l1rec->mask[ip] ||
492 l2rec->a[ipb] <= 0.0 || l2rec->bb[ipb] <= 0.0 ) {
496 m0 = 1.0 + 0.005 *
l1rec->solz[ip];
497 Kd[ip] = m0 * l2rec->a[ipb]
498 + m1 * (1.0 - m2 * exp( m3 * l2rec->a[ipb])) * l2rec->bb[ipb]
499 * (1.0 - m4 * (
l1rec->sw_bb[
band] / l2rec->bb[ipb]));
542 const float m1 = 4.18;
543 const float m2 = 0.52;
544 const float m3 = -10.80;
546 const float n1 = 7.41;
547 const float n2 = 0.13;
548 const float n3 = 4.36;
549 const float n4 = -0.0051;
550 const float n5 = 0.0094;
551 const float n6 = 1.78;
552 const float p = 1.14;
553 const float radCon =
M_PI / 180.0;
555 float m0, sasw, D0,
f,
lambda, Kd;
559 l1str *
l1rec = l2rec->l1rec;
562 printf(
"IOP-based Kd_lee product requires iop model selection (iop_opt). ");
563 printf(
"Using default model.\n");
568 for (ip = 0; ip <
l1rec->npix; ip++) {
572 sasw = asin(sin(radCon *
l1rec->solz[ip]) / 1.34);
573 f = n1 * (n2 - exp(-n3 * (
lambda / 490.))) - (n4 * (
lambda / 490.) + n5) * exp(n6 * (
l1rec->solz[ip] / 30.));
574 D0 = (
f / cos(sasw)) +
p * (1.0 -
f);
576 if (
l1rec->mask[ip] ||
577 l2rec->a[ipb] <= 0.0 || l2rec->bb[ipb] <= 0.0) {
581 m0 = 1.0 + 0.005 *
l1rec->solz[ip];
582 Kd = m0 * l2rec->a[ipb]
583 + m1 * (1.0 - m2 * exp(m3 * l2rec->a[ipb])) * l2rec->bb[ipb];
619 void Zphotic_lee(l2str *l2rec, l2prodstr *
p,
float Zp[]);
631 for (ip = 0; ip < l2rec->l1rec->npix; ip++) {
633 Kd[ip] = 1.0 / Zp[ip];
636 l2rec->l1rec->flags[ip] |=
PRODFAIL;
667 static int firstCall = 1;
669 static float alg_lambda[16], alg_inp[16];
671 static float *
b1, *w1, *w2, *
mean, *sd, b2;
672 static float *xnorm, *alayer;
673 static int32 nrrs, n_input, n_norm, n_nodes;
674 static int32 *bnd_ptr;
677 filehandle *
l1file = l2rec->l1rec->l1file;
691 if ((bnd_ptr = (int32 *) calloc(
l1file->nbands, sizeof (int32))) ==
NULL) {
692 printf(
"-E- : Error allocating memory to bnd_ptr in get_Kd\n");
695 if ((filedir = getenv(
"OCDATAROOT")) ==
NULL) {
696 printf(
"-E- %s, %d: OCDATAROOT env variable undefined.\n",
701 switch (
l1file->sensorID) {
703 strcat(
filename,
"/seawifs/iop/kd_jamet/seawifs_kd_jamet.dat");
706 strcat(
filename,
"/meris/iop/kd_jamet/meris_kd_jamet.dat");
710 "-E- %s, %d: Kd_jamet can only be generated for the SEAWIFS instrument\n",
715 printf(
"Loading Kd coefficient table %s\n",
filename);
718 fprintf(
stderr,
"-E- %s, %d: unable to open %s for reading\n",
726 while (com_ln == 1) {
728 fprintf(
stderr,
"-E- %s, %d: Error reading %s\n",
732 if (
line[0] !=
';') com_ln = 0;
734 if (sscanf(
line,
"%d", &nrrs) != 1) {
735 fprintf(
stderr,
"-E- %s, %d: Error reading %s\n",
739 for (
i = 0;
i < nrrs;
i++) {
740 fgets(
line, 800, fp);
741 sscanf(
line,
"%f", &alg_lambda[
i]);
744 n_norm = n_input + 1;
749 while (com_ln == 1) {
750 fgets(
line, 800, fp);
751 if (
line[0] !=
';') com_ln = 0;
753 sscanf(
line,
"%d", &n_nodes);
755 b1 = malloc(n_nodes *
sizeof (
float));
756 w1 = malloc(n_nodes * n_norm *
sizeof (
float));
757 w2 = malloc(n_nodes *
sizeof (
float));
758 mean = malloc(n_norm *
sizeof (
float));
759 sd = malloc(n_norm *
sizeof (
float));
760 xnorm = malloc(n_input *
sizeof (
float));
761 alayer = malloc(n_nodes *
sizeof (
float));
765 (xnorm ==
NULL) || (alayer ==
NULL)) {
766 fprintf(
stderr,
"-E- %s, %d: allocation of Kd weights failed\n",
774 while (com_ln == 1) {
775 fgets(
line, 800, fp);
776 if (
line[0] !=
';') com_ln = 0;
779 for (
i = 0;
i < n_nodes;
i++) {
780 fgets(
line, 800, fp);
781 sscanf(
line,
"%d %d %f", &poub, &poub, &
b1[
i]);
783 fgets(
line, 800, fp);
784 sscanf(
line,
"%d %d %f", &poub, &poub, &b2);
785 for (
j = 0;
j < n_input;
j++)
786 for (
i = 0;
i < n_nodes;
i++) {
787 fgets(
line, 800, fp);
788 sscanf(
line,
"%d %d %f", &poub, &poub, (w1 +
i + n_nodes *
j));
790 for (
j = 0;
j < n_nodes;
j++) {
791 fgets(
line, 800, fp);
792 sscanf(
line,
"%d %d %f", &poub, &poub, &w2[
j]);
798 while (com_ln == 1) {
799 fgets(
line, 800, fp);
800 if (
line[0] !=
';') com_ln = 0;
803 for (
i = 1;
i < n_norm;
i++) {
804 fgets(
line, 800, fp);
808 while (com_ln == 1) {
809 fgets(
line, 800, fp);
810 if (
line[0] !=
';') com_ln = 0;
812 sscanf(
line,
"%f", &sd[0]);
813 for (
i = 1;
i < n_norm;
i++) {
814 fgets(
line, 800, fp);
815 sscanf(
line,
"%f", &sd[
i]);
821 printf(
"Kd_jamet band assignment:\n");
822 printf(
"Alg wave inst wave inst band\n");
823 for (
i = 0;
i < nrrs;
i++) {
825 printf(
"%7.2f %7.2f %3d\n", alg_lambda[
i],
826 l1file->fwave[bnd_ptr[
i]], bnd_ptr[
i]);
833 for (ip = 0; ip < l2rec->l1rec->npix; ip++) {
834 ipb = ip *
l1file->nbands;
839 if (l2rec->l1rec->mask[ip]) bad_prd = 1;
852 for (
i = 0;
i < nrrs;
i++) {
853 alg_inp[
i] = l2rec->Rrs[ ipb + bnd_ptr[
i] ];
854 if (alg_inp[
i] <
BAD_FLT + 1) bad_prd = 1;
860 l2rec->l1rec->flags[ip] |=
PRODFAIL;
862 for (
i = 0;
i < n_input;
i++)
863 xnorm[
i] = ((2. / 3.) *(alg_inp[
i] -
mean[
i])) / sd[
i];
867 for (
i = 0;
i < n_nodes;
i++) {
869 for (
j = 0;
j < n_input;
j++) {
870 alayer[
i] += (xnorm[
j] * *(w1 +
i + n_nodes *
j));
872 alayer[
i] = 1.715905 * (
float) tanh((2. / 3.) *
876 for (
j = 0,
y = 0.;
j < n_nodes;
j++)
877 y += (alayer[
j] * w2[
j]);
881 y = 1.5 * (
y + b2) * sd[n_input] +
mean[n_input];
882 *(Kd + ip) = (
float) pow(10., (
double)
y);
909 const float factor = 0.7;
911 static int ib443, ib490, ib620, ib665, ib645, ib469, ib859, ib865, firstCall = 1;
914 if (firstCall == 1) {
922 if (ib645 < 0 || ib469 < 0 || ib859 < 0) {
933 if (ib443 < 0 || ib490 < 0 || ib620 < 0 || ib665 < 0 || ib865 < 0) {
934 printf(
"Kd_rhos: incompatible sensor wavelengths for this algorithm\n");
937 printf(
"Kd_rhos: Using the Meris band averaging for this product\n");
945 for (ip = 0; ip < l2rec->l1rec->npix; ip++) {
947 ipb = l2rec->l1rec->l1file->nbands*ip;
950 if (l2rec->Rrs[ipb + ib645] <= 0.0 || l2rec->Rrs[ipb + ib469] <= 0.0 || l2rec->Rrs[ipb + ib859] <= 0.0) {
952 l2rec->l1rec->flags[ip] |=
PRODFAIL;
954 Kd[ip] = factor * (l2rec->l1rec->rhos[ipb + ib645] - l2rec->l1rec->rhos[ipb + ib859])
955 / (l2rec->l1rec->rhos[ipb + ib469] - l2rec->l1rec->rhos[ipb + ib859]);
959 for (ip = 0; ip < l2rec->l1rec->npix; ip++) {
961 ipb = l2rec->l1rec->l1file->nbands*ip;
964 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) {
966 l2rec->l1rec->flags[ip] |=
PRODFAIL;
968 Kd[ip] = factor * ((l2rec->l1rec->rhos[ipb + ib620] + l2rec->l1rec->rhos[ipb + ib665]) / 2 - l2rec->l1rec->rhos[ipb + ib865])
969 / ((l2rec->l1rec->rhos[ipb + ib443] + l2rec->l1rec->rhos[ipb + ib490]) / 2 - l2rec->l1rec->rhos[ipb + ib865]);
981 void get_Kd(l2str *l2rec, l2prodstr *
p,
float prod[]) {
993 Kd_lee(l2rec,
p->prod_ix, prod);
997 Kd532(l2rec,
p->prod_ix, prod);
1021 printf(
"Error: %s : Unknown product specifier: %d\n", __FILE__,
p->cat_ix);
int32 l1file(int32 sdfid, int32 *nsamp, int32 *nscans, int16 *dtynum)
void get_Kd(l2str *l2rec, l2prodstr *p, float prod[])
float mean(float *xs, int sample_size)
PARAM_TYPE_NONE Default value No parameter is buried in the product name name_prefix is case insensitive string compared to the product name PARAM_TYPE_VIS_WAVE The visible wavelength bands from the sensor are buried in the product name The product name is compared by appending and name_suffix ie aph_412_giop where prod_ix will be set to PARAM_TYPE_IR_WAVE same search method as PARAM_TYPE_VIS_WAVE except only wavelength above are looped through but prod_ix is still based ie aph_2_giop for the second band
void Kd532(l2str *l2rec, int flag, float k532[])
void Kd_PAR_lee(l2str *l2rec, float *Kd)
void Kd_PAR_morel(l2str *l2rec, int depth, float *Kd)
void Kd490_morel(l2str *l2rec, float *Kd)
int bindex_get(int32_t wave)
void Kd490_mueller(l2str *l2rec, float k490[])
double precision function f(R1)
void Kd490_obpg(l2str *l2rec, float k490[])
void Kd_jamet(l2str *l2rec, int band, float *Kd)
void nKd_lin(l2str *l2rec, int band, float *nKd)
void get_iops(l2str *l2rec, int32_t iop_opt)
char filename[FILENAME_MAX]
integer, parameter double
instead the metadata field ProcessingEnvinronment is filled in from the output of a call to the POSIX compliant function uname from within the L1B code A small bug in L1B_Tables an incorrect comparison of RVS coefficients for TEBs to RVS coefficients for RSBs was being made This was replaced with a comparison between TEB coefficients This error never resulted in an incorrect RVS correction but did lead to recalculating the coefficients for each detector in a thermal band even if the coefficients were the same for all detectors To reduce to overall size of the reflective LUT HDF fill values were eliminated from all LUTs previously dimensioned where and where NUM_TIMES is the number of time dependent table pieces In Preprocess a small error where the trailing dropped scan counter was incremented when the leading dropped scan counter should have been was fixed This counter is internal only and is not yet used for any chiefly to casting of were added to make it LINUX compatible Output of code run on LINUX machines displays differences of at most scaled sector incalculable values of the Emissive calibration factor b1
int windex(float wave, float twave[], int ntwave)
void Zphotic_lee(l2str *l2rec, l2prodstr *p, float Zp[])
void Kd_rhos(l2str *l2rec, float *Kd)
void Kd_lee(l2str *l2rec, int band, float *Kd)
spectral diffuse attenuation using Lee, et. (2005, 2016)
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
PGE01 indicating that PGE02 PGE01 V6 for and PGE01 V2 for MOD03 were used to produce the granule By convention adopted in all MODIS Terra PGE02 code versions are The fourth digit of the PGE02 version denotes the LUT version used to produce the granule The source of the metadata environment variable ProcessingCenter was changed from a QA LUT value to the Process Configuration A sign used in error in the second order term was changed to a
void Zhl_morel(l2str *l2rec, float *Zhl)
void Kd490_KD2(l2str *l2rec, float *Kd)