15 #include <boost/math/interpolators/barycentric_rational.hpp>
30 int*
year,
int* month,
int*
day);
33 float* elev,
int* ls_flag,
float* windsp,
float* wv);
84 if (
status != DTDB_SUCCESS) {
85 std::cerr <<
"DbAlgLand:: Base class initialization failure" << std::endl;
88 status = initialize_LUT_data( imap );
92 for (
int j = 0;
j < 7;
j++) {
93 for (
int k =
j;
k <=
j + 3;
k++) {
95 for (
int i =
j;
i <=
j + 3;
i++) {
98 densol_[
j][
k-
j] = xdenom;
101 for (
int j = 0;
j < 5;
j++) {
102 for (
int k =
j;
k <=
j + 3;
k++) {
104 for (
int i =
j;
i <=
j + 3;
i++) {
107 denscn_[
j][
k-
j] = xdenom;
121 int status = DTDB_SUCCESS;
124 string config_file =
static_cast<ddstr*
>(imap[
"config_file"])->
str;
125 int num_lines =
static_cast<ddval<int>*
>(imap[
"num_lines"])->
val;
126 int num_pixels =
static_cast<ddval<int>*
>(imap[
"num_pixels"])->
val;
127 int start_year =
static_cast<ddval<int>*
>(imap[
"start_year"])->
val;
128 int start_month =
static_cast<ddval<int>*
>(imap[
"start_month"])->
val;
129 int start_day =
static_cast<ddval<int>*
>(imap[
"start_day"])->
val;
134 char nc4_file[255] =
"";
136 if (nc4_str.empty()) {
139 nc4_str.copy(nc4_file, nc4_str.length());
140 char cfile[255] =
"";
141 config_file.copy(cfile, config_file.length());
145 &num_pixels, &plat->pts[0][0], &plon->
pts[0][0],
146 &start_year, &start_month, &start_day );
151 &ler_edge_[0], season, dateline_);
154 &ler_edge_[0], season, dateline_);
157 &ler_edge_[0], season, dateline_);
175 map<string, ddata*> imap)
181 size_t iy =
start[0];
182 size_t ix =
start[1];
192 for (
size_t i=0;
i<21;
i++) {
200 if ((solz_ > 84.0) || (solz_ < 0.0) || (senz_ < 0.0) || (senz_ > 90.0) ||
201 (raa_ < 0.0) || (raa_ > 180.0) || (ws_ < 0.0) || (ws_ > 99.0)) {
213 compute_glint_angle(glint_angle_);
214 compute_scatter_angle(scatter_angle_);
216 compute_dstar( iy, ix );
221 cm_->compute_1( iy, ix, mask_cm_, snow_1, snow_2 );
224 double cossza = cos(solz_*DEGtoRAD);
225 for (
int i=0;
i<NTWL;
i++) {
227 rfl_[
i] *= (cossza/
M_PI);
229 for (
size_t il=0; il<=2; il++) {
230 for (
size_t ip=0; ip<=2; ip++) {
232 rfla_[
i][il][ip] *= (cossza/
M_PI);
242 compute_gas_correction();
243 for (
int ib = 0; ib < NTWL; ib++) {
244 rfl_[ib] *= gasc_[ib];
248 compute_sr( iy, ix );
252 compute_ler( iy, ix );
257 cm_->compute_2( iy, ix, mask_cm_, snow_2 );
259 smoke_->compute( iy, ix, mask_smoke_ );
260 pyrocb_->compute( iy, ix, mask_pyrocb_ );
261 ha_smoke_->compute( iy, ix, mask_ha_smoke_ );
263 if (mask_smoke_ == 1 || mask_pyrocb_ == 1 || mask_ha_smoke_ == 1) {
268 cloud_mask_ = mask_cm_;
270 mask_cm_ = cloud_mask_;
275 if (bcloudmask_ && cloud_mask_) {
318 &height_, &ls_flag, &ws_, &pwv_);
321 mask_cm_ = (mask_cm_ >= 0) ? mask_cm_ :
DFILL_SHORT;
323 float aotmax = (mask_cm_==0) ? 30.0 : 5.0;
338 lOut_.aerosol_type = 8;
341 lOut_.aerosol_type = 5;
343 if (lOut_.ae > 1.2 && lOut_.aot550 > 0.4) {
344 lOut_.aerosol_type = 4;
346 if (mask_smoke_ == 1 && lOut_.aot550 >
DFILL_TEST) {
347 lOut_.aerosol_type = 1;
349 if (mask_ha_smoke_ == 1 && lOut_.aot550 >
DFILL_TEST) {
350 lOut_.aerosol_type = 2;
352 if (mask_pyrocb_ == 1 && lOut_.aot550 >
DFILL_TEST) {
353 lOut_.aerosol_type = 3;
355 if (lOut_.aot550 >
DFILL_TEST && lOut_.aot550 < 0.2) {
356 lOut_.aerosol_type = 6;
358 if (dstar_ > 1.1 && lOut_.aot550 >
DFILL_TEST) {
359 lOut_.aerosol_type = 0;
361 if (lOut_.ae < 0.1 && ob[20] < 0.78 && lOut_.aot550 > 0.4) {
362 lOut_.aerosol_type = 0;
372 qual_flag_ = (lOut_.aot550 <
DFILL_TEST) ? 0 : 3;
373 aerosol_type_ = lOut_.aerosol_type;
374 error_flag_ = lOut_.alg_flag;
376 scatter_ang_ = scatter_angle_;
377 glint_ang_ = glint_angle_;
380 aot_550_ = lOut_.aot550;
385 for (
int ib=0; ib<NOWL+1; ib++ ) {
392 for (
int ib=0; ib<NLWL; ib++ ) {
393 sr_[ib] = lOut_.sr[ib];
394 ssa_[ib] = lOut_.ssa[ib];;
399 rfl_[ib] *= (
M_PI/cossza);
403 vector<float> tba, yba;
405 tba.push_back(410.0);
410 tba.push_back(490.0);
415 tba.push_back(550.0);
420 tba.push_back(670.0);
425 using boost::math::barycentric_rational;
426 barycentric_rational<float>
interp(move(tba), move(yba), 2);
447 int status = DTDB_SUCCESS;
452 float psi = acos( cos(solz_*DEGtoRAD)*cos(senz_*DEGtoRAD) -
453 sin(solz_*DEGtoRAD)*sin(senz_*DEGtoRAD) *
454 cos(raa_*DEGtoRAD) );
455 sca_ = 180.0 - psi / DEGtoRAD;
456 gla_ = psi / DEGtoRAD;
457 amf_ = 1.0/cos(solz_*DEGtoRAD) + 1.0/cos(senz_*DEGtoRAD);
470 float ratio = (btd11_ - A) / (btd8_ - B);
471 dstar_ = (ratio >= 5.0) ?
DFILL_FLOAT : exp(ratio);
479 int ilat = floor((lat_ + 90.0)*10.0);
480 if (ilat >= 1800) ilat = 1800-1;
481 if (ilat < 0) ilat = 0;
482 int ilon = floor((lon_ + 180.0)*10.0);
483 if (ilon >= 3600) ilon = 3600-1;
484 if (ilon < 0) ilon = 0;
486 if (dateline_ == 0 || ilon > ler_start_[0]) {
487 sx = ilon - ler_start_[0];
489 sx = ilon + dateline_;
491 int sy = ilat - ler_start_[1];
493 if (ndvi_ < NDVI1_CUTOFF) {
495 }
else if (ndvi_ < NDVI2_CUTOFF) {
500 float c670[4], sr670;
502 for (
int i = 0;
i < 4;
i++) {
503 c670[
i] = scl_lut_->SC650_FWD_L[nidx][
i][sy][sx];
505 sr670 = vsr_lut_->SR670_ALL_L[sy][sx]/100.0;
507 for (
int i = 0;
i < 4;
i++) {
508 c670[
i] = scl_lut_->SC650_ALL_L[nidx][
i][sy][sx];
510 sr670 = vsr_lut_->SR670_ALL_L[sy][sx]/100.0;
513 if (c670[0]>0 || c670[1]>0 || c670[2]>0 || c670[3]>0) {
515 (c670[0] + sca_*(c670[1] + sca_*(c670[2] + sca_*c670[3])))/100.0;
517 sfref670 = (sfref670 < 0.0) ? sr670 : sfref670;
532 int status = DTDB_SUCCESS;
553 int ilat = floor((lat_ + 90.0)*10.0);
554 if (ilat >= 1800) ilat = 1800-1;
555 if (ilat < 0) ilat = 0;
556 int ilon = floor((lon_ + 180.0)*10.0);
557 if (ilon >= 3600) ilon = 3600-1;
558 if (ilon < 0) ilon = 0;
560 if (dateline_ == 0 || ilon > ler_start_[0]) {
561 sx = ilon - ler_start_[0];
563 sx = ilon + dateline_;
565 int sy = ilat - ler_start_[1];
567 if (ndvi_ < NDVI1_CUTOFF) {
569 }
else if (ndvi_ < NDVI2_CUTOFF) {
574 float c412[4], sr412;
575 float c488[4], sr488;
576 float c670[4], sr670;
577 sr412 = vsr_lut_->SR412_ALL_L[sy][sx];
578 sr488 = vsr_lut_->SR488_ALL_L[sy][sx];
579 sr670 = vsr_lut_->SR670_ALL_L[sy][sx];
591 for (
int i = 0;
i < 4;
i++) {
592 c412[
i] = scl_lut_->SC412_FWD_L[nidx][
i][sy][sx];
593 c488[
i] = scl_lut_->SC470_FWD_L[nidx][
i][sy][sx];
594 c670[
i] = scl_lut_->SC650_FWD_L[nidx][
i][sy][sx];
597 for (
int i = 0;
i < 4;
i++) {
598 c412[
i] = scl_lut_->SC412_ALL_L[nidx][
i][sy][sx];
599 c488[
i] = scl_lut_->SC470_ALL_L[nidx][
i][sy][sx];
600 c670[
i] = scl_lut_->SC650_ALL_L[nidx][
i][sy][sx];
606 if (c412[0]>0 || c412[1]>0 || c412[2]>0 || c412[3]>0) {
608 (c412[0] + sca_*(c412[1] + sca_*(c412[2] + sca_*c412[3])))/100.0;
610 if (c488[0]>0 || c488[1]>0 || c488[2]>0 || c488[3]>0) {
612 (c488[0] + sca_*(c488[1] + sca_*(c488[2] + sca_*c488[3])))/100.0;
614 if (c670[0]>0 || c670[1]>0 || c670[2]>0 || c670[3]>0) {
616 (c670[0] + sca_*(c670[1] + sca_*(c670[2] + sca_*c670[3])))/100.0;
619 sfref488 = (sfref488 < 0.0) ? sr488 : sfref488;
620 sfref670 = (sfref670 < 0.0) ? sr670 : sfref670;
637 int status = DTDB_SUCCESS;
651 int ilat = floor((lat_ + 90.0)*10.0);
652 if (ilat >= 1800) ilat = 1800-1;
653 if (ilat < 0) ilat = 0;
654 int ilon = floor((lon_ + 180.0)*10.0);
655 if (ilon >= 3600) ilon = 3600-1;
656 if (ilon < 0) ilon = 0;
657 ilat = floor((90.0 - lat_)*12.0);
658 if (ilat >= 2160) ilat = 2160-1;
659 if (ilat < 0) ilat = 0;
660 ilon = floor((lon_ + 180.0)*12.0);
661 if (ilon >= 4320) ilon = 4320-1;
662 if (ilon < 0) ilon = 0;
665 compute_pressure(height_, tmp0, pteran_, tmp1);
666 double convrt = 0.005729577951;
676 float xtemp1 = solz_ / (convrt*10000.);
677 float xtemp2 = sin(xtemp1);
678 xtemp1 = cos(xtemp1);
681 xzlog1 = log(1.0/xtemp1);
683 float ztemp1 = raa_/(convrt*10000.0);
685 cphir_ = cos(ztemp1*2.0);
687 float ytemp1 = senz_/(convrt*10000.0);
688 float ytemp2 = sin(ytemp1);
689 ytemp1 = cos(ytemp1);
692 xlog1 = log(1.0/ytemp1);
694 phs_ = -0.375*xtemp1*xtemp2*ytemp2;
695 phsr_ = 2.0*phs_/(3.0*ytemp1*xtemp1*xtemp1);
698 for (
int i = 0;
i < 10;
i++) {
700 if (
xzlog[
i] >= xzlog1)
break;
708 for (
int i = 0;
i < 8;
i++) {
710 if (
xlog[
i] >= xlog1)
break;
717 float indmax =
indsol + 3;
725 xnom = (xzlog1 -
xzlog[
i])*xnom;
739 xnom = (xlog1 -
xlog[
i])*xnom;
749 for (
int i = 0;
i < 4;
i++) {
750 for (
int k = 0;
k < 4;
k++) {
756 float sfref488 = sr488_;
757 float sfref670 = sr670_;
759 float grref = sfref670;
777 int ipt_1[2] = { 0, 10400 };
778 int ipt_2[2] = { 0, 130 };
779 int lamtb1[5] = { 0, 2080, 4160, 6240, 8320 };
780 int lamtb2[5] = { 0, 26, 52, 78, 104 };
781 float ez670[2], t670[2], sb670[2];
782 float ez412[2], t412[2], sb412[2];
783 float ez488[2], t488[2], sb488[2];
785 float pwtlo = (pteran_ - .4) / .6;
786 float pwthi = (pcloud_ - .4) / .6;
788 float alb670 = NC_[
NC670];
789 float alb412 = NC_[
NC412];
790 float alb488 = NC_[
NC488];
798 for (
int ip = 0; ip < 2; ip++) {
800 int i670_1 = ipt_1[ip] + lamtb1[3] +
iofset;
801 int i670_2 = ipt_2[ip] + lamtb2[3];
803 int i412_1 = ipt_1[ip] + lamtb1[0] +
iofset;
804 int i412_2 = ipt_2[ip] + lamtb2[0];
806 int i488_1 = ipt_1[ip] + lamtb1[2] +
iofset;
807 int i488_2 = ipt_2[ip] + lamtb2[2];
810 interx(i670_1, i670_2,
rhot_band::W670, ez670[ip], t670[ip], sb670[ip]);
812 interx(i412_1, i412_2,
rhot_band::W410, ez412[ip], t412[ip], sb412[ip]);
814 interx(i488_1, i488_2,
rhot_band::W490, ez488[ip], t488[ip], sb488[ip]);
817 qgc670 = ez670[ip] + grref*t670[ip] / (1 - grref*sb670[ip]);
818 qcc670 = ez670[ip] + clref*t670[ip] / (1 - clref*sb670[ip]);
821 qcc412 = ez412[ip] + clref*t412[ip] / (1 - clref*sb412[ip]);
823 qgc488 = ez488[ip] + sfref488*t488[ip] / (1 - sfref488*sb488[ip]);
824 qcc488 = ez488[ip] + clref*t488[ip] / (1 - clref*sb488[ip]);
837 qgc670 = pwtlo*qsl670 + qgc670*(1. - pwtlo);
838 qcc670 = pwthi*qsh670 + qcc670*(1. - pwthi);
839 qdif670 = qsl670 - qgc670;
841 qgc412 = pwtlo*qsl412 + qgc412*(1. - pwtlo);
842 qcc412 = pwthi*qsh412 + qcc412*(1. - pwthi);
845 qgc488 = pwtlo*qsl488 + qgc488*(1. - pwtlo);
846 qcc488 = pwthi*qsh488 + qcc488*(1. - pwthi);
847 qdif488 = qsl488 - qgc488;
871 for (
int ip = 0; ip < 2; ip++) {
873 int i670_1 = ipt_1[ip] + lamtb1[3] +
iofset;
874 int i670_2 = ipt_2[ip] + lamtb2[3] ;
876 int i412_1 = ipt_1[ip] + lamtb1[0] +
iofset;
877 int i412_2 = ipt_2[ip] + lamtb2[0];
879 int i488_1 = ipt_1[ip] + lamtb1[2] +
iofset;
880 int i488_2 = ipt_2[ip] + lamtb2[2];
882 interx(i670_1, i670_2,
rhot_band::W670, ez670[ip], t670[ip], sb670[ip]);
883 interx(i412_1, i412_2,
rhot_band::W410, ez412[ip], t412[ip], sb412[ip]);
884 interx(i488_1, i488_2,
rhot_band::W490, ez488[ip], t488[ip], sb488[ip]);
886 qgc670x = ez670[ip] + grr*t670[ip] / (1 - grr*sb670[ip]);
887 qcc670x = ez670[ip] + clref*t670[ip] / (1 - clref*sb670[ip]);
888 qgc412x = ez412[ip] + grr*t412[ip] / (1 - grr*sb412[ip]);
889 qcc412x = ez412[ip] + clref*t412[ip] / (1 - clref*sb412[ip]);
890 qgc488x = ez488[ip] + grr*t488[ip] / (1 - grr*sb488[ip]);
891 qcc488x = ez488[ip] + clref*t488[ip] / (1 - clref*sb488[ip]);
902 d670 = alb670 - ez670[ip];
903 d412 = alb412 - ez412[ip];
904 d488 = alb488 - ez488[ip];
907 r670_10 = 1. / (t670[ip] / d670 + sb670[ip]);
908 r412_10 = 1. / (t412[ip] / d412 + sb412[ip]);
909 r488_10 = 1. / (t488[ip] / d488 + sb488[ip]);
919 float pwtlo_base = 1.0;
920 qgc670x = pwtlo_base*qsl670
921 + qgc670x*(1. - pwtlo_base);
922 qcc670x = pwthi*qsh670 + qcc670x*(1. - pwthi);
924 qgc412x = pwtlo_base*qsl412
925 + qgc412x*(1. - pwtlo_base);
926 qcc412x = pwthi*qsh412 + qcc412x*(1. - pwthi);
928 qgc488x = pwtlo_base*qsl488
929 + qgc488x*(1. - pwtlo_base);
930 qcc488x = pwthi*qsh488 + qcc488x*(1. - pwthi);
934 d670 = alb670 - ez670[ip];
935 d412 = alb412 - ez412[ip];
936 d488 = alb488 - ez488[ip];
938 r670_04 = 1. / (t670[ip] / d670 + sb670[ip]);
939 rl670 = pwtlo_base*r670_10 +
940 (1. - pwtlo_base)*r670_04;
941 rh670 = pwthi*r670_10 + (1. - pwthi)*r670_04;
943 r412_04 = 1. / (t412[ip] / d412 + sb412[ip]);
944 rl412 = pwtlo_base*r412_10 +
945 (1. - pwtlo_base)*r412_04;
946 rh412 = pwthi*r412_10 + (1. - pwthi)*r412_04;
948 r488_04 = 1. / (t488[ip] / d488 + sb488[ip]);
949 rl488 = pwtlo_base*r488_10 +
950 (1. - pwtlo_base)*r488_04;
951 rh488 = pwthi*r488_10 + (1. - pwthi)*r488_04;
967 if (qcc670x - qgc670x != 0.0) {
968 cl670 = (alb670 - qgc670x) / (qcc670x - qgc670x);
969 cl412 = (alb412 - qgc412x) / (qcc412x - qgc412x);
970 cl488 = (alb488 - qgc488x) / (qcc488x - qgc488x);
981 if (cl670 > 0.0 && cl670 < 1.0) {
983 alb670 = (alb670 - cl670*qcc670x) / (1. - cl670);
984 for (
int ip = 0; ip < 2; ip++) {
985 d670 = alb670 - ez670[ip];
988 r670_10 = 1. / (t670[ip] / d670 + sb670[ip]);
994 r670_04 = 1.0 / (t670[ip] / d670 + sb670[ip]);
995 grref = pwtlo*r670_10 +
996 (1. - pwtlo)*r670_04;
1002 }
else if (cl670 >= 1.0) {
1004 grref = r670_10*pwtlo + r670_04*(1. - pwtlo);
1005 clref = r670_10*pwthi + r670_04*(1. - pwthi);
1008 grref = r670_10*pwtlo + r670_04*(1. - pwtlo);
1024 }
else if (cl670 > 1.0) {
1029 ler412 = grr + cl412*(clref - grr);
1030 ler488 = grr + cl488*(clref - grr);
1031 ler670 = grr + cl670*(clref - grr);
1034 ler412_ = ler412*100;
1035 ler488_ = ler488*100;
1036 ler670_ = ler670*100;
1053 int status = DTDB_SUCCESS;
1072 int status = DTDB_SUCCESS;
1079 for (
int i = 0;
i < 4;
i++) {
1081 for (
int k = 0;
k < 4;
k++) {
1082 inot = inot + mt_lut_->LOGI0[l]*cofs_[m];
1083 zone = zone + mt_lut_->Z1I0[l]*cofs_[m];
1084 ztwo = ztwo + mt_lut_->Z2I0[l]*cofs_[m];
1085 tran = tran + mt_lut_->TI0[l]*cofs_[m];
1091 inot = pow(10.0,inot);
1092 float ione = zone*phs_*inot;
1093 float itwo = ztwo*phsr_*phs_*inot;
1096 ozero = inot + ione*cphi_ + itwo*cphir_;
1098 osb = mt_lut_->SB[i2];
1112 int status = DTDB_SUCCESS;
1114 for (
int iw=0; iw<NLWL; iw++) {
1124 lOut_.aerosol_type = 8;