53 #define MAXMODEL MAXAERMOD
60 static int32_t first_solz;
61 static int32_t first_senz;
62 static int32_t first_phi;
63 static int32_t first_scatt;
64 static int32_t first_dtnwave;
65 static int32_t first_dtntheta;
68 static double radeg =
RADEG;
69 static float p0 =
STDPR;
71 static int have_ms = 0;
72 static int have_rh = 0;
73 static int have_sd = 0;
74 static int use_rh = 0;
75 static int use_netcdf = 0;
78 static int32_t Maxband;
119 model = (aermodstr *) malloc(
sizeof (aermodstr));
120 model->angstrom = (
float*) malloc(
nbands *
sizeof (
float));
121 model->extc = (
float*) malloc(
nbands *
sizeof (
float));
123 model->albedo = (
float*) malloc(
nbands *
sizeof (
float));
127 model->acost = (
float*) malloc(
nbands * nsolz * nphi * nsenz *
sizeof (
float));
128 model->bcost = (
float*) malloc(
nbands * nsolz * nphi * nsenz *
sizeof (
float));
129 model->ccost = (
float*) malloc(
nbands * nsolz * nphi * nsenz *
sizeof (
float));
141 model->ams_all = (
float*) malloc(
nbands * nsolz * nphi * nsenz *
sizeof (
float));
142 model->bms_all = (
float*) malloc(
nbands * nsolz * nphi * nsenz *
sizeof (
float));
143 model->cms_all = (
float*) malloc(
nbands * nsolz * nphi * nsenz *
sizeof (
float));
144 model->dms_all = (
float*) malloc(
nbands * nsolz * nphi * nsenz *
sizeof (
float));
145 model->ems_all = (
float*) malloc(
nbands * nsolz * nphi * nsenz *
sizeof (
float));
190 static aermodtabstr *aertab =
NULL;
209 static int loaded = 0;
210 static int interpol = 0;
211 static int32_t *iwatab;
212 static int32_t *iwdtab;
214 static int32_t iwnir_s = -1;
215 static int32_t iwnir_l = -1;
217 static int imm50 = -1;
218 static int imc50 = -1;
219 static int imc70 = -1;
220 static int imt90 = -1;
221 static int imt99 = -1;
226 static float airmass;
228 static int32_t evalmask = 0;
229 static int32_t aer_opt = 0;
230 static float airmass_plp;
231 static float airmass_sph;
234 if (*(
double*)
a > *(
double*)
b)
return 1;
235 else if (*(
double*)
a < *(
double*)
b)
return -1;
247 float a1, a2, a3, a4, a5, a6, d1;
258 d1 =
y[0]*(1.0 / a1 + 1.0 / a2 + 1.0 / a3)
259 - a2 * a3 *
y[1] / (a1 * a4 * a5)
260 + a1 * a3 *
y[2] / (a2 * a4 * a6)
261 - a1 * a2 *
y[3] / (a3 * a5 * a6);
265 a1 =
x[n - 1] -
x[n - 4];
266 a2 =
x[n - 1] -
x[n - 3];
267 a3 =
x[n - 1] -
x[n - 2];
268 a4 =
x[n - 2] -
x[n - 4];
269 a5 =
x[n - 2] -
x[n - 3];
270 a6 =
x[n - 3] -
x[n - 4];
272 d1 = -a2 * a3 *
y[n - 4] / (a6 * a4 * a1)
273 + a1 * a3 *
y[n - 3] / (a6 * a5 * a2)
274 - a1 * a2 *
y[n - 2] / (a4 * a5 * a3)
275 +
y[n - 1]*(1.0 / a1 + 1.0 / a2 + 1.0 / a3);
282 static void read_dimension_size(
const char* file_name,
int nc_id,
const char* dim_name, int32_t *length) {
287 status = nc_inq_dimid (nc_id, dim_name, &dim_id);
289 printf(
"-E- %s: Error looking for dimension %s from %s.\n", __FILE__, dim_name, file_name);
292 status = nc_inq_dimlen(nc_id, dim_id, &dim_length);
294 printf(
"-E- %s: Error reading dimension %s from %s.\n", __FILE__, dim_name, file_name);
297 *length = (int32_t) dim_length;
301 static void read_lut_variable(
const char*
file,
int nc_id,
const char* var_name,
float*
data) {
305 status = nc_inq_varid(nc_id, var_name, &var_id);
307 printf(
"-E- %s: Error looking for variable %s from %s.\n", __FILE__, var_name,
file);
310 status = nc_get_var_float(nc_id, var_id,
data);
312 printf(
"-E- %s: Error reading variable %s from %s.\n", __FILE__, var_name,
file);
326 int32_t aer_nwave, nsolz, nsenz, nphi, nscatt, dtran_nwave, dtran_ntheta;
333 char file [FILENAME_MAX] =
"";
334 char path [FILENAME_MAX] =
"";
336 int iw,
im,
is, iwbase,
i;
337 static int firstCall = 1;
339 if (firstCall == 1) {
340 if ((iwatab = (int32_t *) calloc(nwave,
sizeof (int32_t))) ==
NULL) {
341 printf(
"Unable to allocate space for iwatab.\n");
344 if ((iwdtab = (int32_t *) calloc(nwave,
sizeof (int32_t))) ==
NULL) {
345 printf(
"Unable to allocate space for iwdtab.\n");
351 printf(
"Loading aerosol models from %s\n", aermodfile);
353 for (
im = 0;
im < nmodels + 1;
im++) {
359 strcat(
file, aermodfile);
366 if(access(
file, R_OK) == -1) {
368 strcat(
file, aermodfile);
371 strcat(
file,
".hdf");
379 strcat(
file, aermodfile);
380 strcat(
file,
"_default.nc");
384 if(access(
file, R_OK) == -1) {
386 strcat(
file, aermodfile);
387 strcat(
file,
"_default.hdf");
394 printf(
"-E- %s: Error opening file %s.\n", __FILE__,
file);
400 read_dimension_size(
file, nc_id,
"wave", &aer_nwave);
401 read_dimension_size(
file, nc_id,
"solz", &nsolz);
402 read_dimension_size(
file, nc_id,
"senz", &nsenz);
403 read_dimension_size(
file, nc_id,
"phi", &nphi);
405 read_dimension_size(
file, nc_id,
"dtran_wave", &dtran_nwave);
406 read_dimension_size(
file, nc_id,
"dtran_theta", &dtran_ntheta);
408 read_dimension_size(
file, nc_id,
"nwave", &aer_nwave);
409 read_dimension_size(
file, nc_id,
"nsolz", &nsolz);
410 read_dimension_size(
file, nc_id,
"nsenz", &nsenz);
411 read_dimension_size(
file, nc_id,
"nphi", &nphi);
412 read_dimension_size(
file, nc_id,
"nscatt", &nscatt);
413 read_dimension_size(
file, nc_id,
"dtran_nwave", &dtran_nwave);
414 read_dimension_size(
file, nc_id,
"dtran_ntheta", &dtran_ntheta);
423 printf(
"Number of Wavelengths %d\n", aer_nwave);
424 printf(
"Number of Solar Zenith Angles %d\n", nsolz);
425 printf(
"Number of View Zenith Angles %d\n", nsenz);
426 printf(
"Number of Relative Azimuth Angles %d\n", nphi);
427 printf(
"Number of Scattering Angles %d\n", nscatt);
428 printf(
"Number of Diffuse Transmittance Wavelengths %d\n", dtran_nwave);
429 printf(
"Number of Diffuse Transmittance Zenith Angles %d\n", dtran_ntheta);
434 first_scatt = nscatt;
435 first_dtnwave = dtran_nwave;
436 first_dtntheta = dtran_ntheta;
439 if ((aertab = (aermodtabstr *) calloc(1,
sizeof (aermodtabstr))) ==
NULL) {
440 printf(
"Unable to allocate space for aerosol table.\n");
444 aertab->nmodel = nmodels;
445 aertab->nwave = aer_nwave;
446 aertab->nsolz = nsolz;
447 aertab->nsenz = nsenz;
449 aertab->nscatt = nscatt;
451 aertab->wave = (
float *) malloc(aer_nwave *
sizeof (
float));
452 aertab->solz = (
float *) malloc(nsolz *
sizeof (
float));
453 aertab->senz = (
float *) malloc(nsenz *
sizeof (
float));
454 aertab->phi = (
float *) malloc(nphi *
sizeof (
float));
456 aertab->scatt =
NULL;
458 aertab->scatt = (
float *) malloc(nscatt *
sizeof (
float));
460 aertab->dtran_nwave = dtran_nwave;
461 aertab->dtran_ntheta = dtran_ntheta;
463 aertab->dtran_wave = (
float *) malloc(dtran_nwave *
sizeof (
float));
464 aertab->dtran_theta = (
float *) malloc(dtran_ntheta *
sizeof (
float));
465 aertab->dtran_airmass = (
float *) malloc(dtran_ntheta *
sizeof (
float));
468 if ((aertab->model = (aermodstr **) calloc(1, (nmodels + 1) *
sizeof (aermodstr*))) ==
NULL) {
469 printf(
"Unable to allocate space for %d aerosol models.\n", nmodels + 1);
472 for (
i = 0;
i < nmodels + 1;
i++) {
473 if ((aertab->model[
i] =
alloc_aermodstr(aer_nwave + 1, nscatt, nphi, nsolz, nsenz, dtran_ntheta)) ==
NULL) {
474 printf(
"Unable to allocate space for aerosol model %d.\n",
im);
482 read_lut_variable(
file, nc_id,
"scatt", aertab->scatt);
483 read_lut_variable(
file, nc_id,
"wave", aertab->wave);
484 read_lut_variable(
file, nc_id,
"solz", aertab->solz);
485 read_lut_variable(
file, nc_id,
"senz", aertab->senz);
486 read_lut_variable(
file, nc_id,
"phi", aertab->phi);
487 read_lut_variable(
file, nc_id,
"dtran_wave", aertab->dtran_wave);
488 read_lut_variable(
file, nc_id,
"dtran_theta", aertab->dtran_theta);
493 if ((aertab->nsolz != first_solz) || (aertab->nsenz != first_senz) ||
494 (aertab->nphi != first_phi) || (aertab->nscatt != first_scatt) ||
495 (aertab->dtran_nwave != first_dtnwave) || (aertab->dtran_ntheta != first_dtntheta)) {
496 printf(
"-E- %s, %d: Error, Aerosol table %s\n",
497 __FILE__, __LINE__,
file);
498 printf(
" has different dimensions from previous tables\n");
506 strncpy(aertab->model[
im]->name,
"default", 32);
508 status = nc_get_att_float(nc_id, NC_GLOBAL,
"RelativeHumidity", &rh);
510 status = nc_get_att_float(nc_id, NC_GLOBAL,
"Relative Humidity", &rh);
513 aertab->model[
im]->rh = rh;
516 aertab->model[
im]->rh = -1.0;
522 status = nc_get_att_int(nc_id, NC_GLOBAL,
"AerosolFMF", &fmf);
524 printf(
"-E- %s, %d: Error, Aerosol table %s does not have AerosolFMF\n",
525 __FILE__, __LINE__,
file);
529 aertab->model[
im]->sd = sd;
531 status = nc_get_att_short(nc_id, NC_GLOBAL,
"Size Distribution", &sd);
533 aertab->model[
im]->sd = sd;
536 aertab->model[
im]->sd = -1;
542 read_lut_variable(
file, nc_id,
"albedo", aertab->model[
im]->albedo);
543 read_lut_variable(
file, nc_id,
"phase", aertab->model[
im]->phase[0]);
544 read_lut_variable(
file, nc_id,
"acost", aertab->model[
im]->acost);
545 read_lut_variable(
file, nc_id,
"bcost", aertab->model[
im]->bcost);
546 read_lut_variable(
file, nc_id,
"ccost", aertab->model[
im]->ccost);
548 read_lut_variable(
file, nc_id,
"extc", aertab->model[
im]->extc);
551 if(nc_inq_varid(nc_id,
"ams_all", &
status) == NC_NOERR) {
553 read_lut_variable(
file, nc_id,
"ams_all", aertab->model[
im]->ams_all);
554 read_lut_variable(
file, nc_id,
"bms_all", aertab->model[
im]->bms_all);
555 read_lut_variable(
file, nc_id,
"cms_all", aertab->model[
im]->cms_all);
556 read_lut_variable(
file, nc_id,
"dms_all", aertab->model[
im]->dms_all);
557 read_lut_variable(
file, nc_id,
"ems_all", aertab->model[
im]->ems_all);
560 read_lut_variable(
file, nc_id,
"dtran_a", aertab->model[
im]->dtran_a[0]);
561 read_lut_variable(
file, nc_id,
"dtran_b", aertab->model[
im]->dtran_b[0]);
566 iwbase =
windex(865, aertab->wave, aertab->nwave);
567 for (iw = 0; iw < aertab->nwave; iw++) {
569 aertab->model[
im]->angstrom[iw] = -log(aertab->model[
im]->extc[iw] / aertab->model[
im]->extc[iwbase]) /
570 log(aertab->wave[iw] / aertab->wave[iwbase]);
572 aertab->model[
im]->angstrom[iwbase] = aertab->model[
im]->angstrom[iwbase - 1];
576 for (iw = 0; iw < aertab->nwave; iw++) {
577 for (
is = 0;
is < aertab->nscatt;
is++) {
578 aertab->model[
im]->lnphase[iw][
is] = log(aertab->model[
im]->phase[iw][
is]);
580 d1phase1 =
first_deriv(aertab->scatt, &aertab->model[
im]->lnphase[iw][0], 0);
581 d1phaseN =
first_deriv(aertab->scatt, &aertab->model[
im]->lnphase[iw][0], aertab->nscatt);
583 &aertab->model[
im]->lnphase[iw][0],
587 &aertab->model[
im]->d2phase[iw][0]);
592 for (iw = 0; iw < aertab->dtran_nwave; iw++) {
593 for (
is = 0;
is < aertab->dtran_ntheta;
is++) {
594 aertab->dtran_airmass[
is] = 1.0 / cos(aertab->dtran_theta[
is] / radeg);
599 aertab->nmodel = nmodels;
603 if (aertab->nwave != nwave) {
604 printf(
"Number of aerosol LUT wavelengths (%d) is not equal to number of sensor wavelengths (%d).\n",
605 aertab->nwave,nwave);
608 if (aertab->dtran_nwave != nwave) {
609 printf(
"Number of aerosol diffue trans LUT wavelengths (%d) is not equal to number of sensor wavelengths (%d).\n",
610 aertab->dtran_nwave,nwave);
615 printf(
"Wavelengths - Sensor\tAerosol model\tDiffuse transmittance\n");
616 for (iw = 0; iw < nwave; iw++) {
617 iwatab[iw] =
windex(wave[iw], aertab->wave, aertab->nwave);
618 iwdtab[iw] =
windex(wave[iw], aertab->dtran_wave, aertab->dtran_nwave);
619 printf(
"\t %6.2f\t %6.2f\t %6.2f\n", wave[iw],aertab->wave[iwatab[iw]], aertab->dtran_wave[iwdtab[iw]]);
642 #define INDEX(iw,isol,iphi,isen) (iw*aertab->nsolz*aertab->nphi*aertab->nsenz + isol*aertab->nphi*aertab->nsenz + iphi*aertab->nsenz + isen)
657 static float lastsolz = -999.;
658 static float lastsenz = -999.;
659 static float lastphi = -999.;
667 static float *
p, *
q, *
r;
668 static float as000, as100, as010, as110, as001, as011, as101, as111;
669 static float ai000, ai100, ai010, ai110, ai001, ai011, ai101, ai111;
670 static float ac000, ac100, ac010, ac110, ac001, ac011, ac101, ac111;
672 static int *isolz1, *isolz2;
673 static int *isenz1, *isenz2;
674 static int *iphi1, *iphi2;
676 static float *p_ar, *q_ar, *r_ar;
677 static float p_cnst, q_cnst, r_cnst;
678 static int *isolz1_ar, *isolz2_ar, isolz1_cnst, isolz2_cnst;
679 static int *isenz1_ar, *isenz2_ar, isenz1_cnst, isenz2_cnst;
680 static int *iphi1_ar, *iphi2_ar, iphi1_cnst, iphi2_cnst;
685 static int firstCall = 1;
688 if (firstCall == 1) {
691 if ((a_coef[
i] = (
float *) calloc(aertab->nwave, sizeof (
float))) ==
NULL) {
692 printf(
"Unable to allocate space for a_coef.\n");
695 if ((b_coef[
i] = (
float *) calloc(aertab->nwave, sizeof (
float))) ==
NULL) {
696 printf(
"Unable to allocate space for rhoa.\n");
699 if ((c_coef[
i] = (
float *) calloc(aertab->nwave, sizeof (
float))) ==
NULL) {
700 printf(
"Unable to allocate space for rhoa.\n");
705 if ((
geom->gmult == 0) || (interpol == 1)) {
710 isolz1 = &isolz1_cnst;
711 isolz2 = &isolz2_cnst;
712 isenz1 = &isenz1_cnst;
713 isenz2 = &isenz2_cnst;
719 if (((p_ar = (
float *) malloc(aertab->nwave * sizeof (
float)))
721 ((q_ar = (
float *) malloc(aertab->nwave * sizeof (
float)))
723 ((r_ar = (
float *) malloc(aertab->nwave * sizeof (
float)))
725 printf(
"Unable to allocate space for p, q, r weights.\n");
728 if (((isolz1_ar = (
int *) malloc(aertab->nwave * sizeof (
int)))
730 ((isenz1_ar = (
int *) malloc(aertab->nwave * sizeof (
int)))
732 ((iphi1_ar = (
int *) malloc(aertab->nwave * sizeof (
int)))
734 printf(
"Unable to allocate space for interp indicies 1.\n");
737 if (((isolz2_ar = (
int *) malloc(aertab->nwave * sizeof (
int)))
739 ((isenz2_ar = (
int *) malloc(aertab->nwave * sizeof (
int)))
741 ((iphi2_ar = (
int *) malloc(aertab->nwave * sizeof (
int)))
743 printf(
"Unable to allocate space for interp indicies 2.\n");
758 if ((
geom->solz[0] != lastsolz) || (
geom->senz[0] != lastsenz) ||
759 (
geom->phi[0] != lastphi)) {
760 for (
im = 0;
im < aertab->nmodel;
im++)
763 for (iw = 0; iw < aertab->nwave; iw++) {
766 for (
i = 0;
i < aertab->nsolz;
i++) {
767 if (
geom->solz[ig] < aertab->solz[
i])
770 isolz1[iw] =
MAX(
i - 1, 0);
771 isolz2[iw] =
MIN(
i, aertab->nsolz - 1);
772 if (isolz2[iw] != isolz1[iw])
773 r[iw] = (
geom->solz[ig] - aertab->solz[isolz1[iw]]) /
774 (aertab->solz[isolz2[iw]] - aertab->solz[isolz1[iw]]);
779 for (
i = 0;
i < aertab->nsenz;
i++) {
780 if (
geom->senz[ig] < aertab->senz[
i])
783 isenz1[iw] =
MAX(
i - 1, 0);
784 isenz2[iw] =
MIN(
i, aertab->nsenz - 1);
785 if (isenz2[iw] != isenz1[iw])
786 p[iw] = (
geom->senz[ig] - aertab->senz[isenz1[iw]]) /
787 (aertab->senz[isenz2[iw]] - aertab->senz[isenz1[iw]]);
793 for (
i = 0;
i < aertab->nphi;
i++) {
794 if (aphi < aertab->phi[
i])
797 iphi1[iw] =
MAX(
i - 1, 0);
798 iphi2[iw] =
MIN(
i, aertab->nphi - 1);
799 if (iphi2[iw] != iphi1[iw])
800 q[iw] = (aphi - aertab->phi[iphi1[iw]]) /
801 (aertab->phi[iphi2[iw]] - aertab->phi[iphi1[iw]]);
804 if (gmult == 0)
break;
808 lastsolz =
geom->solz[0];
809 lastsenz =
geom->senz[0];
810 lastphi =
geom->phi[0];
817 for (iw = 0; iw < aertab->nwave; iw++) {
822 if (isolz2[ig] == 0) {
823 as000 = aertab->model[
im]->acost[
INDEX(iw, isolz1[ig], 0, isenz1[ig])];
824 as100 = aertab->model[
im]->acost[
INDEX(iw, isolz1[ig], 0, isenz2[ig])];
825 as001 = aertab->model[
im]->acost[
INDEX(iw, isolz2[ig], 0, isenz1[ig])];
826 as101 = aertab->model[
im]->acost[
INDEX(iw, isolz2[ig], 0, isenz2[ig])];
828 ai000 = aertab->model[
im]->bcost[
INDEX(iw, isolz1[ig], 0, isenz1[ig])];
829 ai100 = aertab->model[
im]->bcost[
INDEX(iw, isolz1[ig], 0, isenz2[ig])];
830 ai001 = aertab->model[
im]->bcost[
INDEX(iw, isolz2[ig], 0, isenz1[ig])];
831 ai101 = aertab->model[
im]->bcost[
INDEX(iw, isolz2[ig], 0, isenz2[ig])];
833 ac000 = aertab->model[
im]->ccost[
INDEX(iw, isolz1[ig], 0, isenz1[ig])];
834 ac100 = aertab->model[
im]->ccost[
INDEX(iw, isolz1[ig], 0, isenz2[ig])];
835 ac001 = aertab->model[
im]->ccost[
INDEX(iw, isolz2[ig], 0, isenz1[ig])];
836 ac101 = aertab->model[
im]->ccost[
INDEX(iw, isolz2[ig], 0, isenz2[ig])];
838 a_coef[
im][iw] = (1. - px)*(1. - rx) * as000 + px * rx * as101
839 + (1. - px) * rx * as001 + px * (1. - rx) * as100;
841 b_coef[
im][iw] = (1. - px)*(1. - rx) * ai000 + px * rx * ai101
842 + (1. - px) * rx * ai001 + px * (1. - qx)*(1. - rx) * ai100;
844 c_coef[
im][iw] = (1. - px)*(1. - rx) * ac000 + px * rx * ac101
845 + (1. - px) * rx * ac001 + px * (1. - qx)*(1. - rx) * ac100;
847 as000 = aertab->model[
im]->acost[
INDEX(iw, isolz1[ig], iphi1[ig], isenz1[ig])];
848 as100 = aertab->model[
im]->acost[
INDEX(iw, isolz1[ig], iphi1[ig], isenz2[ig])];
849 as010 = aertab->model[
im]->acost[
INDEX(iw, isolz1[ig], iphi2[ig], isenz1[ig])];
850 as110 = aertab->model[
im]->acost[
INDEX(iw, isolz1[ig], iphi2[ig], isenz2[ig])];
851 as001 = aertab->model[
im]->acost[
INDEX(iw, isolz2[ig], iphi1[ig], isenz1[ig])];
852 as011 = aertab->model[
im]->acost[
INDEX(iw, isolz2[ig], iphi2[ig], isenz1[ig])];
853 as101 = aertab->model[
im]->acost[
INDEX(iw, isolz2[ig], iphi1[ig], isenz2[ig])];
854 as111 = aertab->model[
im]->acost[
INDEX(iw, isolz2[ig], iphi2[ig], isenz2[ig])];
856 ai000 = aertab->model[
im]->bcost[
INDEX(iw, isolz1[ig], iphi1[ig], isenz1[ig])];
857 ai100 = aertab->model[
im]->bcost[
INDEX(iw, isolz1[ig], iphi1[ig], isenz2[ig])];
858 ai010 = aertab->model[
im]->bcost[
INDEX(iw, isolz1[ig], iphi2[ig], isenz1[ig])];
859 ai110 = aertab->model[
im]->bcost[
INDEX(iw, isolz1[ig], iphi2[ig], isenz2[ig])];
860 ai001 = aertab->model[
im]->bcost[
INDEX(iw, isolz2[ig], iphi1[ig], isenz1[ig])];
861 ai011 = aertab->model[
im]->bcost[
INDEX(iw, isolz2[ig], iphi2[ig], isenz1[ig])];
862 ai101 = aertab->model[
im]->bcost[
INDEX(iw, isolz2[ig], iphi1[ig], isenz2[ig])];
863 ai111 = aertab->model[
im]->bcost[
INDEX(iw, isolz2[ig], iphi2[ig], isenz2[ig])];
865 ac000 = aertab->model[
im]->ccost[
INDEX(iw, isolz1[ig], iphi1[ig], isenz1[ig])];
866 ac100 = aertab->model[
im]->ccost[
INDEX(iw, isolz1[ig], iphi1[ig], isenz2[ig])];
867 ac010 = aertab->model[
im]->ccost[
INDEX(iw, isolz1[ig], iphi2[ig], isenz1[ig])];
868 ac110 = aertab->model[
im]->ccost[
INDEX(iw, isolz1[ig], iphi2[ig], isenz2[ig])];
869 ac001 = aertab->model[
im]->ccost[
INDEX(iw, isolz2[ig], iphi1[ig], isenz1[ig])];
870 ac011 = aertab->model[
im]->ccost[
INDEX(iw, isolz2[ig], iphi2[ig], isenz1[ig])];
871 ac101 = aertab->model[
im]->ccost[
INDEX(iw, isolz2[ig], iphi1[ig], isenz2[ig])];
872 ac111 = aertab->model[
im]->ccost[
INDEX(iw, isolz2[ig], iphi2[ig], isenz2[ig])];
874 a_coef[
im][iw] = (1. - px)*(1. - qx)*(1. - rx) * as000 + px * qx * rx * as111
875 + px * (1. - qx) * rx * as101 + (1. - px) * qx * (1. - rx) * as010
876 + px * qx * (1. - rx) * as110 + (1. - px)*(1. - qx) * rx * as001
877 + (1. - px) * qx * rx * as011 + px * (1. - qx)*(1. - rx) * as100;
879 b_coef[
im][iw] = (1. - px)*(1. - qx)*(1. - rx) * ai000 + px * qx * rx * ai111
880 + px * (1. - qx) * rx * ai101 + (1. - px) * qx * (1. - rx) * ai010
881 + px * qx * (1. - rx) * ai110 + (1. - px)*(1. - qx) * rx * ai001
882 + (1. - px) * qx * rx * ai011 + px * (1. - qx)*(1. - rx) * ai100;
884 c_coef[
im][iw] = (1. - px)*(1. - qx)*(1. - rx) * ac000 + px * qx * rx * ac111
885 + px * (1. - qx) * rx * ac101 + (1. - px) * qx * (1. - rx) * ac010
886 + px * qx * (1. - rx) * ac110 + (1. - px)*(1. - qx) * rx * ac001
887 + (1. - px) * qx * rx * ac011 + px * (1. - qx)*(1. - rx) * ac100;
893 *
a = &a_coef[modnum][0];
894 *
b = &b_coef[modnum][0];
895 *
c = &c_coef[modnum][0];
907 sq = sqrt(pow(
index, 2.0) - 1.0 + pow(mu, 2.0));
908 r2 = pow((mu - sq) / (mu + sq), 2.0);
909 q1 = (1.0 - pow(mu, 2.0) - mu * sq) / (1.0 - pow(mu, 2.0) + mu * sq);
911 return (r2 * (q1 * q1 + 1.0) / 2.0);
932 float **
a,
float **
b,
float **
c,
float **d,
float **e)
934 static float lastsolz = -999.;
935 static float lastsenz = -999.;
936 static float lastphi = -999.;
946 static float *
p, *
q, *
r;
947 static float as000, as100, as010, as110, as001, as011, as101, as111;
948 static float ai000, ai100, ai010, ai110, ai001, ai011, ai101, ai111;
949 static float ac000, ac100, ac010, ac110, ac001, ac011, ac101, ac111;
950 static float ad000, ad100, ad010, ad110, ad001, ad011, ad101, ad111;
951 static float ae000, ae100, ae010, ae110, ae001, ae011, ae101, ae111;
953 static int *isolz1, *isolz2;
954 static int *isenz1, *isenz2;
955 static int *iphi1, *iphi2;
957 static float *p_ar, *q_ar, *r_ar;
958 static float p_cnst, q_cnst, r_cnst;
959 static int *isolz1_ar, *isolz2_ar, isolz1_cnst, isolz2_cnst;
960 static int *isenz1_ar, *isenz2_ar, isenz1_cnst, isenz2_cnst;
961 static int *iphi1_ar, *iphi2_ar, iphi1_cnst, iphi2_cnst;
967 static int firstCall = 1;
969 if (firstCall == 1) {
972 if ((a_coef[
i] = (
float *) calloc(aertab->nwave, sizeof (
float))) ==
NULL) {
973 printf(
"Unable to allocate space for a_coef.\n");
976 if ((b_coef[
i] = (
float *) calloc(aertab->nwave, sizeof (
float))) ==
NULL) {
977 printf(
"Unable to allocate space for b_coef.\n");
980 if ((c_coef[
i] = (
float *) calloc(aertab->nwave, sizeof (
float))) ==
NULL) {
981 printf(
"Unable to allocate space for c_coef.\n");
984 if ((d_coef[
i] = (
float *) calloc(aertab->nwave, sizeof (
float))) ==
NULL) {
985 printf(
"Unable to allocate space for d_coef.\n");
989 if ((e_coef[
i] = (
float *) calloc(aertab->nwave, sizeof (
float))) ==
NULL) {
990 printf(
"Unable to allocate space for e_coef.\n");
996 if ((
geom->gmult == 0) || (interpol == 1)) {
1001 isolz1 = &isolz1_cnst;
1002 isolz2 = &isolz2_cnst;
1003 isenz1 = &isenz1_cnst;
1004 isenz2 = &isenz2_cnst;
1005 iphi1 = &iphi1_cnst;
1006 iphi2 = &iphi2_cnst;
1009 if (((p_ar = (
float *) malloc(aertab->nwave * sizeof (
float)))
1011 ((q_ar = (
float *) malloc(aertab->nwave * sizeof (
float)))
1013 ((r_ar = (
float *) malloc(aertab->nwave * sizeof (
float)))
1015 printf(
"Unable to allocate space for p, q, r weights.\n");
1018 if (((isolz1_ar = (
int *) malloc(aertab->nwave * sizeof (
int)))
1020 ((isenz1_ar = (
int *) malloc(aertab->nwave * sizeof (
int)))
1022 ((iphi1_ar = (
int *) malloc(aertab->nwave * sizeof (
int)))
1024 printf(
"Unable to allocate space for interp indicies 1.\n");
1027 if (((isolz2_ar = (
int *) malloc(aertab->nwave * sizeof (
int)))
1029 ((isenz2_ar = (
int *) malloc(aertab->nwave * sizeof (
int)))
1031 ((iphi2_ar = (
int *) malloc(aertab->nwave * sizeof (
int)))
1033 printf(
"Unable to allocate space for interp indicies 2.\n");
1048 if (
geom->solz[0] != lastsolz ||
geom->senz[0] != lastsenz ||
1049 geom->phi[0] != lastphi) {
1050 for (
im = 0;
im < aertab->nmodel;
im++)
1053 for (iw = 0; iw < aertab->nwave; iw++) {
1056 for (
i = 0;
i < aertab->nsolz;
i++) {
1057 if (
geom->solz[ig] < aertab->solz[
i])
1060 isolz1[iw] =
MAX(
i - 1, 0);
1061 isolz2[iw] =
MIN(
i, aertab->nsolz - 1);
1062 if (isolz2[iw] != isolz1[iw])
1063 r[iw] = (
geom->solz[ig] - aertab->solz[isolz1[iw]]) /
1064 (aertab->solz[isolz2[iw]] - aertab->solz[isolz1[iw]]);
1069 for (
i = 0;
i < aertab->nsenz;
i++) {
1070 if (
geom->senz[ig] < aertab->senz[
i])
1073 isenz1[iw] =
MAX(
i - 1, 0);
1074 isenz2[iw] =
MIN(
i, aertab->nsenz - 1);
1075 if (isenz2[iw] != isenz1[iw])
1076 p[iw] = (
geom->senz[ig] - aertab->senz[isenz1[iw]]) /
1077 (aertab->senz[isenz2[iw]] - aertab->senz[isenz1[iw]]);
1083 for (
i = 0;
i < aertab->nphi;
i++) {
1084 if (aphi < aertab->phi[
i])
1087 iphi1[iw] =
MAX(
i - 1, 0);
1088 iphi2[iw] =
MIN(
i, aertab->nphi - 1);
1089 if (iphi2[iw] != iphi1[iw])
1090 q[iw] = (aphi - aertab->phi[iphi1[iw]]) /
1091 (aertab->phi[iphi2[iw]] - aertab->phi[iphi1[iw]]);
1094 if (gmult == 0)
break;
1098 lastsolz =
geom->solz[0];
1099 lastsenz =
geom->senz[0];
1100 lastphi =
geom->phi[0];
1110 for (iw = 0; iw < aertab->nwave; iw++) {
1115 if (isolz2[ig] == 0) {
1116 as000 = aertab->model[
im]->ams_all[
INDEX(iw, isolz1[ig], 0, isenz1[ig])];
1117 as100 = aertab->model[
im]->ams_all[
INDEX(iw, isolz1[ig], 0, isenz2[ig])];
1118 as001 = aertab->model[
im]->ams_all[
INDEX(iw, isolz2[ig], 0, isenz1[ig])];
1119 as101 = aertab->model[
im]->ams_all[
INDEX(iw, isolz2[ig], 0, isenz2[ig])];
1121 ai000 = aertab->model[
im]->bms_all[
INDEX(iw, isolz1[ig], 0, isenz1[ig])];
1122 ai100 = aertab->model[
im]->bms_all[
INDEX(iw, isolz1[ig], 0, isenz2[ig])];
1123 ai001 = aertab->model[
im]->bms_all[
INDEX(iw, isolz2[ig], 0, isenz1[ig])];
1124 ai101 = aertab->model[
im]->bms_all[
INDEX(iw, isolz2[ig], 0, isenz2[ig])];
1126 ac000 = aertab->model[
im]->cms_all[
INDEX(iw, isolz1[ig], 0, isenz1[ig])];
1127 ac100 = aertab->model[
im]->cms_all[
INDEX(iw, isolz1[ig], 0, isenz2[ig])];
1128 ac001 = aertab->model[
im]->cms_all[
INDEX(iw, isolz2[ig], 0, isenz1[ig])];
1129 ac101 = aertab->model[
im]->cms_all[
INDEX(iw, isolz2[ig], 0, isenz2[ig])];
1131 ad000 = aertab->model[
im]->dms_all[
INDEX(iw, isolz1[ig], 0, isenz1[ig])];
1132 ad100 = aertab->model[
im]->dms_all[
INDEX(iw, isolz1[ig], 0, isenz2[ig])];
1133 ad001 = aertab->model[
im]->dms_all[
INDEX(iw, isolz2[ig], 0, isenz1[ig])];
1134 ad101 = aertab->model[
im]->dms_all[
INDEX(iw, isolz2[ig], 0, isenz2[ig])];
1136 ae000 = aertab->model[
im]->ems_all[
INDEX(iw, isolz1[ig], 0, isenz1[ig])];
1137 ae100 = aertab->model[
im]->ems_all[
INDEX(iw, isolz1[ig], 0, isenz2[ig])];
1138 ae001 = aertab->model[
im]->ems_all[
INDEX(iw, isolz2[ig], 0, isenz1[ig])];
1139 ae101 = aertab->model[
im]->ems_all[
INDEX(iw, isolz2[ig], 0, isenz2[ig])];
1141 a_coef[
im][iw] = (1. - px)*(1. - rx) * as000 + px * rx * as101
1142 + (1. - px) * rx * as001 + px * (1. - rx) * as100;
1144 b_coef[
im][iw] = (1. - px)*(1. - rx) * ai000 + px * rx * ai101
1145 + (1. - px) * rx * ai001 + px * (1. - qx)*(1. - rx) * ai100;
1147 c_coef[
im][iw] = (1. - px)*(1. - rx) * ac000 + px * rx * ac101
1148 + (1. - px) * rx * ac001 + px * (1. - qx)*(1. - rx) * ac100;
1150 d_coef[
im][iw] = (1. - px)*(1. - rx) * ad000 + px * rx * ad101
1151 + (1. - px) * rx * ad001 + px * (1. - qx)*(1. - rx) * ad100;
1153 e_coef[
im][iw] = (1. - px)*(1. - rx) * ae000 + px * rx * ae101
1154 + (1. - px) * rx * ae001 + px * (1. - qx)*(1. - rx) * ae100;
1158 as000 = aertab->model[
im]->ams_all[
INDEX(iw, isolz1[ig], iphi1[ig], isenz1[ig])];
1159 as100 = aertab->model[
im]->ams_all[
INDEX(iw, isolz2[ig], iphi1[ig], isenz1[ig])];
1160 as010 = aertab->model[
im]->ams_all[
INDEX(iw, isolz1[ig], iphi2[ig], isenz1[ig])];
1161 as110 = aertab->model[
im]->ams_all[
INDEX(iw, isolz2[ig], iphi2[ig], isenz1[ig])];
1162 as001 = aertab->model[
im]->ams_all[
INDEX(iw, isolz1[ig], iphi1[ig], isenz2[ig])];
1163 as011 = aertab->model[
im]->ams_all[
INDEX(iw, isolz1[ig], iphi2[ig], isenz2[ig])];
1164 as101 = aertab->model[
im]->ams_all[
INDEX(iw, isolz2[ig], iphi1[ig], isenz2[ig])];
1165 as111 = aertab->model[
im]->ams_all[
INDEX(iw, isolz2[ig], iphi2[ig], isenz2[ig])];
1167 ai000 = aertab->model[
im]->bms_all[
INDEX(iw, isolz1[ig], iphi1[ig], isenz1[ig])];
1168 ai100 = aertab->model[
im]->bms_all[
INDEX(iw, isolz2[ig], iphi1[ig], isenz1[ig])];
1169 ai010 = aertab->model[
im]->bms_all[
INDEX(iw, isolz1[ig], iphi2[ig], isenz1[ig])];
1170 ai110 = aertab->model[
im]->bms_all[
INDEX(iw, isolz2[ig], iphi2[ig], isenz1[ig])];
1171 ai001 = aertab->model[
im]->bms_all[
INDEX(iw, isolz1[ig], iphi1[ig], isenz2[ig])];
1172 ai011 = aertab->model[
im]->bms_all[
INDEX(iw, isolz1[ig], iphi2[ig], isenz2[ig])];
1173 ai101 = aertab->model[
im]->bms_all[
INDEX(iw, isolz2[ig], iphi1[ig], isenz2[ig])];
1174 ai111 = aertab->model[
im]->bms_all[
INDEX(iw, isolz2[ig], iphi2[ig], isenz2[ig])];
1176 ac000 = aertab->model[
im]->cms_all[
INDEX(iw, isolz1[ig], iphi1[ig], isenz1[ig])];
1177 ac100 = aertab->model[
im]->cms_all[
INDEX(iw, isolz2[ig], iphi1[ig], isenz1[ig])];
1178 ac010 = aertab->model[
im]->cms_all[
INDEX(iw, isolz1[ig], iphi2[ig], isenz1[ig])];
1179 ac110 = aertab->model[
im]->cms_all[
INDEX(iw, isolz2[ig], iphi2[ig], isenz1[ig])];
1180 ac001 = aertab->model[
im]->cms_all[
INDEX(iw, isolz1[ig], iphi1[ig], isenz2[ig])];
1181 ac011 = aertab->model[
im]->cms_all[
INDEX(iw, isolz1[ig], iphi2[ig], isenz2[ig])];
1182 ac101 = aertab->model[
im]->cms_all[
INDEX(iw, isolz2[ig], iphi1[ig], isenz2[ig])];
1183 ac111 = aertab->model[
im]->cms_all[
INDEX(iw, isolz2[ig], iphi2[ig], isenz2[ig])];
1185 ad000 = aertab->model[
im]->dms_all[
INDEX(iw, isolz1[ig], iphi1[ig], isenz1[ig])];
1186 ad100 = aertab->model[
im]->dms_all[
INDEX(iw, isolz2[ig], iphi1[ig], isenz1[ig])];
1187 ad010 = aertab->model[
im]->dms_all[
INDEX(iw, isolz1[ig], iphi2[ig], isenz1[ig])];
1188 ad110 = aertab->model[
im]->dms_all[
INDEX(iw, isolz2[ig], iphi2[ig], isenz1[ig])];
1189 ad001 = aertab->model[
im]->dms_all[
INDEX(iw, isolz1[ig], iphi1[ig], isenz2[ig])];
1190 ad011 = aertab->model[
im]->dms_all[
INDEX(iw, isolz1[ig], iphi2[ig], isenz2[ig])];
1191 ad101 = aertab->model[
im]->dms_all[
INDEX(iw, isolz2[ig], iphi1[ig], isenz2[ig])];
1192 ad111 = aertab->model[
im]->dms_all[
INDEX(iw, isolz2[ig], iphi2[ig], isenz2[ig])];
1194 ae000 = aertab->model[
im]->ems_all[
INDEX(iw, isolz1[ig], iphi1[ig], isenz1[ig])];
1195 ae100 = aertab->model[
im]->ems_all[
INDEX(iw, isolz2[ig], iphi1[ig], isenz1[ig])];
1196 ae010 = aertab->model[
im]->ems_all[
INDEX(iw, isolz1[ig], iphi2[ig], isenz1[ig])];
1197 ae110 = aertab->model[
im]->ems_all[
INDEX(iw, isolz2[ig], iphi2[ig], isenz1[ig])];
1198 ae001 = aertab->model[
im]->ems_all[
INDEX(iw, isolz1[ig], iphi1[ig], isenz2[ig])];
1199 ae011 = aertab->model[
im]->ems_all[
INDEX(iw, isolz1[ig], iphi2[ig], isenz2[ig])];
1200 ae101 = aertab->model[
im]->ems_all[
INDEX(iw, isolz2[ig], iphi1[ig], isenz2[ig])];
1201 ae111 = aertab->model[
im]->ems_all[
INDEX(iw, isolz2[ig], iphi2[ig], isenz2[ig])];
1204 a_coef[
im][iw] = (1. - rx)*(1. - qx)*(1. - px) * as000 + rx * qx * px * as111
1205 + rx * (1. - qx) * px * as101 + (1. - rx) * qx * (1. - px) * as010
1206 + rx * qx * (1. - px) * as110 + (1. - rx)*(1. - qx) * px * as001
1207 + (1. - rx) * qx * px * as011 + rx * (1. - qx)*(1. - px) * as100;
1209 b_coef[
im][iw] = (1. - rx)*(1. - qx)*(1. - px) * ai000 + rx * qx * px * ai111
1210 + rx * (1. - qx) * px * ai101 + (1. - rx) * qx * (1. - px) * ai010
1211 + rx * qx * (1. - px) * ai110 + (1. - rx)*(1. - qx) * px * ai001
1212 + (1. - rx) * qx * px * ai011 + rx * (1. - qx)*(1. - px) * ai100;
1214 c_coef[
im][iw] = (1. - rx)*(1. - qx)*(1. - px) * ac000 + rx * qx * px * ac111
1215 + rx * (1. - qx) * px * ac101 + (1. - rx) * qx * (1. - px) * ac010
1216 + rx * qx * (1. - px) * ac110 + (1. - rx)*(1. - qx) * px * ac001
1217 + (1. - rx) * qx * px * ac011 + rx * (1. - qx)*(1. - px) * ac100;
1219 d_coef[
im][iw] = (1. - rx)*(1. - qx)*(1. - px) * ad000 + rx * qx * px * ad111
1220 + rx * (1. - qx) * px * ad101 + (1. - rx) * qx * (1. - px) * ad010
1221 + rx * qx * (1. - px) * ad110 + (1. - rx)*(1. - qx) * px * ad001
1222 + (1. - rx) * qx * px * ad011 + rx * (1. - qx)*(1. - px) * ad100;
1224 e_coef[
im][iw] = (1. - rx)*(1. - qx)*(1. - px) * ae000 + rx * qx * px * ae111
1225 + rx * (1. - qx) * px * ae101 + (1. - rx) * qx * (1. - px) * ae010
1226 + rx * qx * (1. - px) * ae110 + (1. - rx)*(1. - qx) * px * ae001
1227 + (1. - rx) * qx * px * ae011 + rx * (1. - qx)*(1. - px) * ae100;
1234 if (
fabs(d_coef[modnum][iwnir_l]) > 1e-9) {
1235 printf(
"non zero cubic term found in longest NIR wavelength of aerosol table. Zia!!\n");
1240 *
a = &a_coef[modnum][0];
1241 *
b = &b_coef[modnum][0];
1242 *
c = &c_coef[modnum][0];
1243 *d = &d_coef[modnum][0];
1244 *e = &e_coef[modnum][0];
1258 return (
x->eps_obs <
y->eps_obs ? -1 : 1);
1261 void model_select_ahmad(int32_t nmodels, int32_t *mindx,
float eps_pred[],
float eps_obs, int32_t *modmin,
1262 int32_t *modmax,
float *modrat) {
1269 for (
im = 0;
im < nmodels;
im++) {
1270 epsilonT[
im].eps_obs = eps_pred[
im];
1271 epsilonT[
im].modnum =
im;
1277 qsort(epsilonT, nmodels,
sizeof (epsilonTstr),
1282 for (
im = 0;
im < nmodels;
im++) {
1283 if (eps_obs < epsilonT[
im].eps_obs)
1294 im1 =
MAX(
MIN(
im - 1, nmodels - 1), 0);
1295 im2 =
MAX(
MIN(
im, nmodels - 1), 0);
1301 *modmin = epsilonT[im1].modnum;
1302 *modmax = epsilonT[im2].modnum;
1303 *modrat = (eps_obs - epsilonT[im1].eps_obs) / (epsilonT[im2].eps_obs - epsilonT[im1].eps_obs);
1307 if (*modmin == *modmax)
1321 float tau_iwnir_l, int32_t modl,
float tau_pred[],
float rho_pred[])
1323 float *
ac, *
bc, *cc, *dc, *ec;
1324 float ext_modl[nwave];
1325 float lg_tau_pred[nwave];
1326 float lg_rho_pred[nwave];
1338 for (iw = 0; iw < nwave; iw++) {
1340 ext_modl[iw] = aertab->model[modl]->extc[iwtab];
1344 for (iw = 0; iw < nwave; iw++) {
1345 tau_pred[iw] = (ext_modl[iw] / ext_modl[iwnir_l]) * tau_iwnir_l;
1346 lg_tau_pred[iw] = log(tau_pred[iw]);
1351 for (iw = 0; iw < nwave; iw++) {
1353 lg_rho_pred[iw] =
ac[iwtab] +
1354 bc[iwtab] * lg_tau_pred[iw] +
1355 cc[iwtab] * pow(lg_tau_pred[iw], 2) +
1356 dc[iwtab] * pow(lg_tau_pred[iw], 3) +
1357 ec[iwtab] * pow(lg_tau_pred[iw], 4);
1358 rho_pred[iw] = exp(lg_rho_pred[iw]);
1374 float tau_iwnir_l, int32_t modl,
float tau_pred[],
float rho_pred[])
1376 float *
ac, *
bc, *cc, *dc, *ec;
1377 float ext_modl[nwave];
1378 float lg_tau_pred[nwave];
1379 float lg_rho_pred[nwave];
1391 for (iw = 0; iw < nwave; iw++) {
1393 ext_modl[iw] = aertab->model[modl]->extc[iwtab];
1397 for (iw = 0; iw < nwave; iw++) {
1398 tau_pred[iw] = (ext_modl[iw] / ext_modl[iwnir_l]) * tau_iwnir_l;
1399 lg_tau_pred[iw] = (tau_pred[iw]);
1404 for (iw = 0; iw < nwave; iw++) {
1406 lg_rho_pred[iw] =
ac[iwtab] +
1407 bc[iwtab] * lg_tau_pred[iw] +
1408 cc[iwtab] * pow(lg_tau_pred[iw], 2) +
1409 dc[iwtab] * pow(lg_tau_pred[iw], 3) +
1410 ec[iwtab] * pow(lg_tau_pred[iw], 4);
1411 rho_pred[iw] = (lg_rho_pred[iw]);
1426 int32_t iwnir_s, int32_t iwnir_l, int32_t nmodels, int32_t mindx1[],
1427 int32_t mindx2[], int32_t mindx3[], geom_str *
geom,
1428 float wv,
float rhoa[],
float rho_aer[], int32_t *mod1_indx,
1429 int32_t *mod2_indx,
float *weight,
float tau_pred_min[],
1430 float tau_pred_max[],
float tg_sol_sm[],
float tg_sen_sm[],
1431 float Lt_sm[], int32_t ip) {
1434 float *
ac, *
bc, *cc, *dc, *ec;
1435 float ext_iwnir_cal;
1436 double ax, bx, cx, fx;
1443 float tau_iwnir_cal;
1444 float *lg_tau_all_wav = (
float*) malloc(nwave *
sizeof (
float));
1445 float *lg_rho_all_wav_pred = (
float*) malloc(nwave *
sizeof (
float));
1446 float **tau_all_wav = (
float**) malloc(nwave *
sizeof (
float*));
1447 float **rho_all_wav_pred = (
float**) malloc(nwave *
sizeof (
float*));
1451 for (
i = 0;
i < nwave;
i++) {
1452 tau_all_wav[
i] = (
float*) malloc((nmodels) *
sizeof (
float));
1453 rho_all_wav_pred[
i] = (
float*) malloc((nmodels) *
sizeof (
float));
1456 float *ext_all_wav = (
float*) malloc(nwave *
sizeof (
float));
1458 int iwtab,
im, modl;
1459 float lg_tau_iwnir_cal;
1461 double *
diff = malloc(nwave *
sizeof (
double));
1462 double *chi = malloc(nmodels *
sizeof (
double));
1463 double *chi_temp = malloc(nmodels *
sizeof (
double));
1467 int min1_indx, min2_indx;
1470 float *noise = malloc(nwave *
sizeof (
float));
1471 static float scaled_lt;
1472 int iwtab_l, iwtab_cal;
1478 float ltSnrFitCoef[16][2] = {
1479 {0.05499859, 0.00008340},
1480 {0.02939470, 0.00009380},
1481 {0.11931482, 0.00008195},
1482 {0.01927545, 0.00009450},
1483 {0.01397522, 0.00010040},
1484 {0.01139088, 0.00016480},
1485 {0.08769538, 0.00007000},
1486 {0.10406925, 0.00008533},
1487 {0.00496291, 0.00014050},
1488 {0.00427147, 0.00013160},
1489 {0.00416994, 0.00021250},
1490 {0.04055895, 0.000197550},
1491 {0.00312263, 0.00018600},
1492 {0.07877732, 0.00049940},
1493 {100000.1, 100000000.1},
1494 {0.00628912, 0.00021160}
1498 float snr_scale[16] = {
1499 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 2, 2, 2
1502 for (
i = 0;
i < nwave;
i++) {
1503 scaled_lt = Lt_sm[ip * nwave +
i];
1504 noise[
i] = (ltSnrFitCoef[
i][0] + ltSnrFitCoef[
i][1] * scaled_lt * snr_scale[
i]);
1508 for (
i = 0;
i < nwave;
i++)
1515 int32_t *mindx = (int32_t*) malloc(nmodels *
sizeof (int32_t));
1519 if (mindx1[0] == mindx2[0]) {
1521 for (
i = 0;
i < 10;
i++)
1522 mindx[
i] = mindx1[
i];
1525 for (
i = 0;
i < 10;
i++) {
1526 mindx[
i] = mindx1[
i];
1527 mindx[
i + 10] = mindx2[
i];
1529 }
else if (mindx3[0] >= mindx1[0]) {
1530 for (
i = 0;
i < 10;
i++) {
1531 mindx[
i] = mindx1[
i];
1532 mindx[
i + 10] = mindx2[
i];
1533 mindx[
i + 20] = mindx3[
i];
1536 for (
i = 0;
i < 10;
i++) {
1537 mindx[
i] = mindx3[
i];
1538 mindx[
i + 10] = mindx1[
i];
1539 mindx[
i + 20] = mindx2[
i];
1559 for (
im = 0;
im < nmodels;
im++) {
1567 iwtab_cal = iwatab[iwnir_cal];
1570 iwtab_cal = iwatab[iwnir_cal];
1573 printf(
"Error: Sensor unkown %d\n",
sensorID);
1581 iwtab_l = iwatab[iwnir_l];
1584 ax = (
double)
ac[iwtab_cal] - log((
double) rhoa[iwnir_cal]);
1586 cx = (
double) cc[iwtab_cal];
1588 fx = bx * bx - 4.0 *
ax*cx;
1589 if (fx > 0.0 && cx != 0.0) {
1590 lg_tau_iwnir_cal = 0.5 * (-bx + sqrt(fx)) / cx;
1591 tau_iwnir_cal = exp(lg_tau_iwnir_cal);
1602 ext_iwnir_cal = aertab->model[modl]->extc[iwtab_cal];
1603 for (iw = 0; iw <= iwtab_l - 1; iw++) {
1605 ext_all_wav[iw] = aertab->model[modl]->extc[iwtab];
1606 tau_all_wav[iw][
im] = (ext_all_wav[iw] / ext_iwnir_cal) * tau_iwnir_cal;
1607 lg_tau_all_wav[iw] = log(tau_all_wav[iw][
im]);
1608 lg_rho_all_wav_pred[iw] =
ac[iwtab] +
bc[iwtab] * lg_tau_all_wav[iw] +
1609 cc[iwtab] * pow(lg_tau_all_wav[iw], 2) +
1610 dc[iwtab] * pow(lg_tau_all_wav[iw], 3) +
1611 ec[iwtab] * pow(lg_tau_all_wav[iw], 4);
1612 rho_all_wav_pred[iw][
im] = exp(lg_rho_all_wav_pred[iw]);
1616 for (iw = iwnir_s; iw <= iwnir_l; iw++) {
1618 diff[iw] = pow((rhoa[iw] - rho_all_wav_pred[iw][
im]), 2);
1619 diff_2 +=
diff[iw]* (1 / noise[iw]) *(tg_sol_sm[ip * nwave + iw] * tg_sol_sm[ip * nwave + iw]);
1622 chi[
im] = sqrt(diff_2 / (iwnir_l - iwnir_s));
1632 for (
i = 0;
i < nmodels;
i++)
1633 chi_temp[
i] = chi[
i];
1635 qsort(chi_temp, nmodels,
sizeof (chi_temp[0]),
cmpfunc);
1639 for (
i = 0;
i < nmodels;
i++) {
1642 else if (chi[
i] == min2)
1653 double weight1 = ((rhoa[iwnir_s] / rhoa[iwnir_l]) - (rho_all_wav_pred[iwnir_s][min1_indx] / rho_all_wav_pred[iwnir_l][min1_indx])) / ((rho_all_wav_pred[iwnir_s][min2_indx] / rho_all_wav_pred[iwnir_l][min2_indx])-(rho_all_wav_pred[iwnir_s][min1_indx] / rho_all_wav_pred[iwnir_l][min1_indx]));
1661 *mod1_indx = mindx[min1_indx];
1662 *mod2_indx = mindx[min2_indx];
1663 for (iw = 0; iw <= iwnir_l; iw++) {
1664 rho_aer[iw] = (1 - weight1) * rho_all_wav_pred[iw][min1_indx] + (weight1) * rho_all_wav_pred[iw][min2_indx];
1665 tau_pred_min[iw] = tau_all_wav[iw][min1_indx];
1666 tau_pred_max[iw] = tau_all_wav[iw][min2_indx];
1669 free(lg_tau_all_wav);
1670 free(lg_rho_all_wav_pred);
1671 for (
i = 0;
i < nwave;
i++) {
1672 free(tau_all_wav[
i]);
1673 free(rho_all_wav_pred[
i]);
1676 free(rho_all_wav_pred);
1697 int32_t nmodels, int32_t mindx[],
1698 geom_str *
geom,
float wv,
float rhoa[],
1699 int32_t *modmin, int32_t *modmax,
float *modrat,
float *epsnir,
1700 float tau_pred_max[],
float tau_pred_min[],
float rho_pred_max[],
float rho_pred_min[],
1701 float tau_aer[],
float rho_aer[]) {
1704 float *
ac, *
bc, *cc, *dc, *ec;
1705 float ext_iwnir_l, ext_iwnir_s;
1706 double ax, bx, cx, fx;
1707 float tau_iwnir_l[nmodels];
1708 float lg_tau_iwnir_s[nmodels], tau_iwnir_s[nmodels];
1709 float lg_rho_iwnir_s_pred[nmodels], rho_iwnir_s_pred[nmodels];
1710 float eps_pred[nmodels];
1714 float lg_tau_iwnir_l;
1715 int iwtab_l, iwtab_s;
1718 static float eps_obs;
1727 eps_obs = rhoa[iwnir_s] / rhoa[iwnir_l];
1737 for (
im = 0;
im < nmodels;
im++) {
1748 iwtab_l = iwatab[iwnir_l];
1749 iwtab_s = iwatab[iwnir_s];
1751 ax = (
double)
ac[iwtab_l] - log((
double) rhoa[iwnir_l]);
1753 cx = (
double) cc[iwtab_l];
1755 fx = bx * bx - 4.0 *
ax*cx;
1756 if (fx > 0.0 && cx != 0.0) {
1757 lg_tau_iwnir_l = 0.5 * (-bx + sqrt(fx)) / cx;
1758 tau_iwnir_l[
im] = exp(lg_tau_iwnir_l);
1766 ext_iwnir_l = aertab->model[modl]->extc[iwtab_l];
1767 ext_iwnir_s = aertab->model[modl]->extc[iwtab_s];
1769 tau_iwnir_s[
im] = (ext_iwnir_s / ext_iwnir_l) * tau_iwnir_l[
im];
1770 lg_tau_iwnir_s[
im] = log(tau_iwnir_s[
im]);
1775 lg_rho_iwnir_s_pred[
im] =
ac[iwtab_s] +
bc[iwtab_s] * lg_tau_iwnir_s[
im] +
1776 cc[iwtab_s] * pow(lg_tau_iwnir_s[
im], 2) +
1777 dc[iwtab_s] * pow(lg_tau_iwnir_s[
im], 3) +
1778 ec[iwtab_s] * pow(lg_tau_iwnir_s[
im], 4);
1780 rho_iwnir_s_pred[
im] = exp(lg_rho_iwnir_s_pred[
im]);
1784 eps_pred[
im] = rho_iwnir_s_pred[
im] / rhoa[iwnir_l];
1820 *modmin = mindx[im1];
1821 *modmax = mindx[im2];
1831 for (iw = 0; iw < nwave; iw++) {
1832 tau_aer[iw] = (1.0 - mwt) * tau_pred_min[iw] + mwt * tau_pred_max[iw];
1833 rho_aer[iw] = (1.0 - mwt) * rho_pred_min[iw] + mwt * rho_pred_max[iw];
1848 int32_t nmodels, int32_t mindx[],
1849 geom_str *
geom,
float wv,
float rhoa[],
1850 int32_t *modmin, int32_t *modmax,
float *modrat,
float *epsnir,
1851 float tau_pred_max[],
float tau_pred_min[],
float rho_pred_max[],
float rho_pred_min[],
1852 float tau_aer[],
float rho_aer[]) {
1855 float *
ac, *
bc, *cc, *dc, *ec;
1856 float ext_iwnir_l, ext_iwnir_s;
1857 double ax, bx, cx, fx;
1858 float tau_iwnir_l[nmodels];
1859 float lg_tau_iwnir_s[nmodels], tau_iwnir_s[nmodels];
1860 float lg_rho_iwnir_s_pred[nmodels], rho_iwnir_s_pred[nmodels];
1861 float eps_pred[nmodels];
1865 float lg_tau_iwnir_l;
1866 int iwtab_l, iwtab_s;
1869 static float eps_obs;
1878 eps_obs = rhoa[iwnir_s] / rhoa[iwnir_l];
1888 for (
im = 0;
im < nmodels;
im++) {
1899 iwtab_l = iwatab[iwnir_l];
1900 iwtab_s = iwatab[iwnir_s];
1902 ax = (
double)
ac[iwtab_l]-(
double) rhoa[iwnir_l];
1904 cx = (
double) cc[iwtab_l];
1906 fx = bx * bx - 4.0 *
ax*cx;
1907 if (fx > 0.0 && cx != 0.0) {
1908 lg_tau_iwnir_l = 0.5 * (-bx + sqrt(fx)) / cx;
1909 tau_iwnir_l[
im] = (lg_tau_iwnir_l);
1917 ext_iwnir_l = aertab->model[modl]->extc[iwtab_l];
1918 ext_iwnir_s = aertab->model[modl]->extc[iwtab_s];
1920 tau_iwnir_s[
im] = (ext_iwnir_s / ext_iwnir_l) * tau_iwnir_l[
im];
1921 lg_tau_iwnir_s[
im] = (tau_iwnir_s[
im]);
1924 printf(
"\nErroneous aerosol option, %d\n", aer_opt);
1925 printf(
"You are using a log-space LUT. The aerosol LUT coefficients need to be in linear-space. Use aer_opt=-18 instead. \n");
1932 lg_rho_iwnir_s_pred[
im] =
ac[iwtab_s] +
bc[iwtab_s] * lg_tau_iwnir_s[
im] +
1933 cc[iwtab_s] * pow(lg_tau_iwnir_s[
im], 2) +
1934 dc[iwtab_s] * pow(lg_tau_iwnir_s[
im], 3) +
1935 ec[iwtab_s] * pow(lg_tau_iwnir_s[
im], 4);
1937 rho_iwnir_s_pred[
im] = (lg_rho_iwnir_s_pred[
im]);
1941 eps_pred[
im] = rho_iwnir_s_pred[
im] / rhoa[iwnir_l];
1970 *modmin = mindx[im1];
1971 *modmax = mindx[im2];
1981 for (iw = 0; iw < nwave; iw++) {
1982 tau_aer[iw] = (1.0 - mwt) * tau_pred_min[iw] + mwt * tau_pred_max[iw];
1983 rho_aer[iw] = (1.0 - mwt) * rho_pred_min[iw] + mwt * rho_pred_max[iw];
2002 static float nw = 1.334;
2005 static float lastsolz = -999.;
2006 static float lastsenz = -999.;
2007 static float lastphi = -999.;
2009 static float *fres1, *fres2;
2010 static float *scatt1, *scatt2;
2011 static float scatt1_cnst, scatt2_cnst, fres1_cnst, fres2_cnst;
2012 static float *scatt1_ar, *scatt2_ar, *fres1_ar, *fres2_ar;
2013 static int firstCall = 1, gmult = 1;
2015 float phase1, phase2;
2018 if (firstCall == 1) {
2021 if ((
phase[
im] = (
float *) calloc(aertab->nwave, sizeof (
float))) ==
NULL) {
2022 printf(
"Unable to allocate space for phase.\n");
2027 if ((
geom->gmult == 0) || (interpol == 1)) {
2029 scatt1 = &scatt1_cnst;
2030 scatt2 = &scatt2_cnst;
2031 fres1 = &fres1_cnst;
2032 fres2 = &fres2_cnst;
2036 (
float *) malloc(aertab->nwave * sizeof (
float))) ==
NULL) {
2037 printf(
"Unable to allocate space for scatt1.\n");
2041 (
float *) malloc(aertab->nwave * sizeof (
float))) ==
NULL) {
2042 printf(
"Unable to allocate space for scatt2.\n");
2046 (
float *) malloc(aertab->nwave * sizeof (
float))) ==
NULL) {
2047 printf(
"Unable to allocate space for fres1.\n");
2051 (
float *) malloc(aertab->nwave * sizeof (
float))) ==
NULL) {
2052 printf(
"Unable to allocate space for fres2.\n");
2064 if ((
geom->solz[0] != lastsolz) || (
geom->senz[0] != lastsenz) ||
2065 (
geom->phi[0] != lastphi)) {
2069 for (
im = 0;
im < aertab->nmodel;
im++)
2073 for (iw = 0; iw < aertab->nwave; iw++) {
2075 temp = sqrt((1.0 -
geom->csenz[ig] *
geom->csenz[ig]) *
2076 (1.0 -
geom->csolz[ig] *
geom->csolz[ig])) *
2077 cos(
geom->phi[ig] / radeg);
2079 MAX(-
geom->csenz[ig] *
geom->csolz[ig] + temp, -1.0)) * radeg;
2081 MIN(
geom->csenz[ig] *
geom->csolz[ig] + temp, 1.0)) * radeg;
2086 if (gmult == 0)
break;
2089 lastsolz =
geom->solz[0];
2090 lastsenz =
geom->senz[0];
2091 lastphi =
geom->phi[0];
2100 for (iw = 0; iw < aertab->nwave; iw++) {
2103 &aertab->model[
im]->lnphase[iw][0],
2104 &aertab->model[
im]->d2phase[iw][0],
2105 aertab->nscatt, scatt1[ig], &phase1);
2107 &aertab->model[
im]->lnphase[iw][0],
2108 &aertab->model[
im]->d2phase[iw][0],
2109 aertab->nscatt, scatt2[ig], &phase2);
2112 exp(phase2)*(fres1[ig] + fres2[ig]);
2116 return (&
phase[modnum][0]);
2125 static int firstCall = 1;
2130 float rhoas1, rhoas2;
2135 iw1 =
windex(765, aertab->wave, aertab->nwave);
2136 iw2 =
windex(865, aertab->wave, aertab->nwave);
2137 if (iw1 == iw2) iw1--;
2142 rhoas1 = aertab->model[modnum]->albedo[iw1] *
phase[iw1] * aertab->model[modnum]->extc[iw1];
2143 rhoas2 = aertab->model[modnum]->albedo[iw2] *
phase[iw2] * aertab->model[modnum]->extc[iw2];
2144 eps = rhoas1 / rhoas2;
2145 cf = log(eps) / (aertab->wave[iw2] - aertab->wave[iw1]);
2169 static int firstCall = 1;
2188 printf(
"\nLoading water-vapor correction coefficients.\n");
2191 f = (a01[iw] + a02[iw] * airmass + cf * (a03[iw] + a04[iw] * airmass))
2192 + (a05[iw] + a06[iw] * airmass + cf * (a07[iw] + a08[iw] * airmass)) * wv
2193 + (a09[iw] + a10[iw] * airmass + cf * (a11[iw] + a12[iw] * airmass)) * wv*wv;
2206 float rhoa[],
float wave[], int32_t nwave,
int iw1,
int iw2,
float rhoas[]) {
2207 float *
ac, *
bc, *cc;
2219 for (iw = iw1; iw <= iw2; iw++) {
2220 ig = iw *
geom->gmult;
2221 if (rhoa[iw] < 1.e-20)
2222 rhoas[iw] = rhoa[iw];
2228 f =
b *
b - 4 *
c * (
a - log((
double) rhoa[iw]));
2230 if (
fabs(
c) > 1.e-20) {
2231 rhoas[iw] = exp(0.5 * (-
b + sqrt(
f)) /
c);
2232 }
else if (
fabs(
a) > 1.e-20 &&
fabs(
b) > 1.e-20) {
2233 rhoas[iw] = pow(rhoa[iw] /
a, 1. /
b);
2239 if (!isfinite(rhoas[iw]) || rhoas[iw] < 1.e-20) {
2253 for (iw = iw1; iw <= iw2; iw++)
2254 rhoas[iw] = rhoa[iw];
2269 float rhoas[],
float wave[], int32_t nwave,
int iw1,
int iw2,
float rhoa[]) {
2270 float *
ac, *
bc, *cc;
2281 for (iw = iw1; iw <= iw2; iw++) {
2282 ig = iw *
geom->gmult;
2287 if (rhoas[iw] < 1.e-20)
2288 rhoa[iw] = rhoas[iw];
2295 rhoa[iw] = exp(
a +
b * lnrhoas +
c * lnrhoas * lnrhoas);
2329 static float lastsolz = -999.;
2330 static float lastsenz = -999.;
2331 static float lastphi = -999.;
2332 static int32_t lastiwl = -999;
2333 static int lastmod = -999;
2335 static int firstCall = 1;
2340 if (firstCall == 1) {
2342 maxwave =
MAX(aertab->nwave, nwave);
2344 if ((
epsilon[
i] = (
float *) calloc(maxwave,
sizeof (
float))) ==
NULL) {
2345 printf(
"Unable to allocate space for epsilon.\n");
2354 if (modnum != lastmod ||
geom->solz[0] != lastsolz ||
2355 geom->senz[0] != lastsenz ||
geom->phi[0] != lastphi ||
2356 iwnir_l != lastiwl) {
2358 int iwnir = iwatab[iwnir_l];
2361 float rhoas1, rhoas2;
2364 if ((lneps = (
float *) calloc(aertab->nwave, sizeof (
float))) ==
NULL) {
2365 printf(
"Unable to allocate space for lneps.\n");
2371 for (iw = 0; iw < aertab->nwave; iw++) {
2372 rhoas1 = aertab->model[
im]->albedo[iw] *
phase[iw] * aertab->model[
im]->extc[iw];
2373 rhoas2 = aertab->model[
im]->albedo[iwnir] *
phase[iwnir] * aertab->model[
im]->extc[iwnir];
2379 for (iw = 0; iw < nwave; iw++) {
2381 if (aertab->wave[iwtab] != wave[iw] && wave[iw] > 0)
2382 epsilon[
im][iw] = exp(
linterp(aertab->wave, lneps, aertab->nwave, wave[iw]));
2388 lastsolz =
geom->solz[0];
2389 lastsenz =
geom->senz[0];
2390 lastphi =
geom->phi[0];
2408 int32_t nmodel, int32_t mindx[], geom_str *
geom,
float wv,
2409 float rhoa[], int32_t iwnir_s, int32_t iwnir_l, int32_t *modmin,
2410 int32_t *modmax,
float *modrat,
float *epsnir) {
2432 if ((rhoas = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
2433 printf(
"Unable to allocate space for rhoas.\n");
2441 for (jm = 0; jm < nmod; jm++) {
2448 if (rhoas[iwnir_l] > 0.0000001)
2449 eps_ret[jm] = rhoas[iwnir_s] / rhoas[iwnir_l];
2455 eps_mod[jm] = eps[iwnir_s];
2457 eps_ave += eps_ret[jm];
2459 if (isfinite(eps_ave))
2472 for (
im = 0;
im < nmodel;
im++) {
2474 eps_err[
im] = eps_ave - eps_mod[
im];
2478 for (
im = 0;
im < nmodel - 1;
im++) {
2479 for (iim =
im + 1; iim < nmodel; iim++)
2480 if (
fabs(eps_err[imod[
im]]) >
fabs(eps_err[imod[iim]])) {
2482 imod[
im ] = imod[iim];
2494 for (iim = 0; iim < nmod; iim++) {
2496 tot_err +=
fabs(eps_err[
im]);
2500 for (iim = 0; iim < nmod; iim++) {
2502 wt = 1.0 -
fabs(eps_err[
im]) / tot_err;
2503 eps_ave += eps_ret[
im] * wt;
2505 eps_ave /= (nmod - 1);
2509 err_m = 0 - FLT_MAX;
2511 for (
im = 0;
im < nmodel;
im++) {
2512 eps_err[
im] = eps_ave - eps_mod[
im];
2513 if (eps_err[
im] >= 0.0) {
2514 if (eps_err[
im] < err_p) {
2515 err_p = eps_err[
im];
2519 if (eps_err[
im] > err_m) {
2520 err_m = eps_err[
im];
2532 }
else if (*modmax < 0) {
2538 *modrat = (eps_ave - eps_mod[*modmin]) / (eps_mod[*modmax] - eps_mod[*modmin]);
2540 *modmin = mindx[*modmin];
2541 *modmax = mindx[*modmax];
2558 return (
x->angstrom <
y->angstrom ? -1 : 1);
2563 static int firstCall = 1;
2569 int ib =
windex(520, aertab->wave, aertab->nwave);
2572 for (
im = 0;
im < aertab->nmodel;
im++) {
2573 alphaT[
im].angstrom = aertab->model[
im]->angstrom[ib];
2574 alphaT[
im].modnum =
im;
2576 qsort(alphaT, aertab->nmodel, sizeof (alphaTstr),
2577 (
int (*)(
const void *,
const void *))
compalphaT);
2582 for (
im = 0;
im < aertab->nmodel;
im++) {
2583 if (angstrom < alphaT[
im].angstrom)
2586 im1 =
MAX(
MIN(
im - 1, aertab->nmodel - 1), 0);
2587 im2 =
MAX(
MIN(
im, aertab->nmodel - 1), 0);
2589 *modmin = alphaT[im1].modnum;
2590 *modmax = alphaT[im2].modnum;
2595 *modrat = (angstrom - alphaT[im1].angstrom) /
2596 (alphaT[im2].angstrom - alphaT[im1].angstrom);
2614 int32_t iwnir_l,
float rhoa[], geom_str *
geom,
float wv,
float taua[]) {
2619 int iwnir = iwatab[iwnir_l];
2624 iwg = iwnir *
geom->gmult;
2626 maxwave =
MAX(aertab->nwave, nwave);
2628 if ((rhoas = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
2629 printf(
"Unable to allocate space for rhoas.\n");
2632 if ((aot = (
float *) calloc(maxwave,
sizeof (
float))) ==
NULL) {
2633 printf(
"Unable to allocate space for aot.\n");
2636 if ((lnaot = (
float *) calloc(maxwave,
sizeof (
float))) ==
NULL) {
2637 printf(
"Unable to allocate space for lnaot.\n");
2645 aot[iwnir] = rhoas[iwnir_l]*(4.0 *
geom->csolz[iwg] *
geom->csenz[iwg])
2646 / (
phase[iwnir] * aertab->model[modnum]->albedo[iwnir]);
2649 for (iw = 0; iw < aertab->nwave; iw++) {
2651 aot[iw] = aot[iwnir] * aertab->model[modnum]->extc[iw] / aertab->model[modnum]->extc[iwnir];
2653 lnaot[iw] = log(aot[iw]);
2658 for (iw = 0; iw < nwave; iw++) {
2660 if (aertab->wave[iwtab] != wave[iw] && wave[iw] > 0)
2661 taua[iw] = exp(
linterp(aertab->wave, lnaot, aertab->nwave, wave[iw]));
2663 taua[iw] = aot[iwtab];
2666 for (iw = 0; iw < nwave; iw++)
2680 float rhoa[], geom_str *
geom,
float tau_pred[])
2682 float *
ac, *
bc, *cc, *dc, *ec;
2683 double ax, bx, cx, fx;
2684 float ext_modl[nwave];
2687 int iwtab_l = iwatab[iwnir_l];
2693 ax = (
double)
ac[iwtab_l] - log((
double) rhoa[iwnir_l]);
2695 cx = (
double) cc[iwtab_l];
2697 fx = bx * bx - 4.0 *
ax*cx;
2698 if (fx > 0.0 && cx != 0.0) {
2699 tau_iwnir_l = exp(0.5*(-bx + sqrt(fx)) / cx);
2705 for (iw = 0; iw < nwave; iw++) {
2707 ext_modl[iw] = aertab->model[modl]->extc[iwtab];
2709 for (iw = 0; iw < nwave; iw++) {
2710 tau_pred[iw] = (ext_modl[iw] / ext_modl[iwnir_l]) * tau_iwnir_l;
2723 float *theta,
int gmult,
float taua[],
float dtran[]) {
2724 static int firstCall = 1;
2725 static float *intexp;
2767 for (iw = 0; iw < nwave; iw++) {
2768 if ((iw == 0) || (gmult != 0)) {
2771 for (
i = 0;
i < aertab->dtran_ntheta;
i++) {
2772 if (theta[ig] < aertab->dtran_theta[
i])
2775 if (
i == aertab->dtran_ntheta) {
2780 i1 =
MIN(
MAX(
i - 1, 0), aertab->dtran_ntheta - 2);
2782 x1 = aertab->dtran_airmass[i1];
2783 x2 = aertab->dtran_airmass[i2];
2784 xbar = 1.0 / cos(theta[ig] / radeg);
2785 wt = (xbar - x1) / (x2 - x1);
2790 a1 = aertab->model[modnum]->dtran_a[iwtab][i1];
2791 b1 = aertab->model[modnum]->dtran_b[iwtab][i1];
2793 a2 = aertab->model[modnum]->dtran_a[iwtab][i2];
2794 b2 = aertab->model[modnum]->dtran_b[iwtab][i2];
2803 y1 = a1 * exp(-
b1 * taua[iw]);
2804 y2 = a2 * exp(-b2 * taua[iw]);
2806 dtran[iw] =
MAX(
MIN((1.0 - wt) * y1 + wt*y2, 1.0), 1e-5);
2817 geom_str *
geom,
float wv,
float pr,
float taur[], int32_t modmin,
2818 int32_t modmax,
float modrat,
float rhoa[],
float taua[],
float tsol[],
2819 float tsen[],
float tauamin[],
float tauamax[],
int taua_opt) {
2826 if ((tsolmin = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
2827 printf(
"Unable to allocate space for tsolmin.\n");
2830 if ((tsolmax = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
2831 printf(
"Unable to allocate space for tsolmax.\n");
2834 if ((tsenmin = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
2835 printf(
"Unable to allocate space for tsenmin.\n");
2838 if ((tsenmax = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
2839 printf(
"Unable to allocate space for tsenmax.\n");
2842 gmult =
geom->gmult;
2843 if (interpol == 1) gmult = 0;
2846 if (taua_opt == 0) {
2851 }
else if (taua_opt == 2) {
2867 for (iw = 0; iw < nwave; iw++) {
2868 ig = iw *
geom->gmult;
2869 taua[iw] = tauamin[iw]*(1.0 - modrat) + tauamax[iw] * modrat;
2870 tsol[iw] = tsolmin[iw]*(1.0 - modrat) + tsolmax[iw] * modrat;
2871 tsen[iw] = tsenmin[iw]*(1.0 - modrat) + tsenmax[iw] * modrat;
2874 tsol[iw] = tsol[iw] * exp(-0.5 * taur[iw] /
geom->csolz[ig]*(
pr / p0 - 1));
2875 tsen[iw] = tsen[iw] * exp(-0.5 * taur[iw] /
geom->csenz[ig] *(
pr / p0 - 1));
2879 tsol[iw] = pow(tsol[iw],
geom->airmass_sph[ig] /
geom->airmass_plp[ig]);
2880 tsen[iw] = pow(tsen[iw],
geom->airmass_sph[ig] /
geom->airmass_plp[ig]);
2904 int32_t iwnir_l, int32_t nmodels, int32_t mindx1[], int32_t mindx2[],
2905 int32_t mindx3[], geom_str *
geom,
float wv,
float rhoa[],
2906 float rho_aer[], int32_t *modmin, int32_t *modmax,
float *modrat,
2907 float tau_pred_min[],
float tau_pred_max[],
float tg_sol_sm[],
2908 float tg_sen_sm[],
float Lt_sm[], int32_t ip) {
2912 printf(
"\nThe multi-scattering spectral matching atmospheric correction method requires\n");
2913 printf(
"ams_all, bms_all, cms_all, dms_all, ems in the aerosol model tables.\n");
2918 if (
spectral_matching(
sensorID, wave, nwave, iwnir_s, iwnir_l, nmodels, mindx1, mindx2, mindx3,
geom, wv, rhoa,
2919 rho_aer, modmin, modmax, modrat, tau_pred_min, tau_pred_max, tg_sol_sm, tg_sen_sm, Lt_sm, ip) == 0) {
2922 for (iw = 0; iw < nwave; iw++) {
2923 rhoa[iw] = rho_aer[iw];
2937 int32_t nmodels, int32_t mindx[],
2938 geom_str *
geom,
float wv,
float rhoa[],
2939 int32_t *modmin, int32_t *modmax,
float *modrat,
float *epsnir,
2940 float tau_pred_min[],
float tau_pred_max[]) {
2943 float rho_pred_min[nwave], rho_pred_max[nwave];
2944 float rho_aer[nwave], tau_aer[nwave];
2947 printf(
"\nThe multi-scattering epsilon atmospheric correction method requires\n");
2948 printf(
"ams_all, bms_all, cms_all, dms_all, ems in the aerosol model tables.\n");
2953 rhoa, modmin, modmax, modrat, epsnir,
2954 tau_pred_max, tau_pred_min, rho_pred_max, rho_pred_min, tau_aer, rho_aer) != 0)
2959 rhoa, modmin, modmax, modrat, epsnir,
2960 tau_pred_max, tau_pred_min, rho_pred_max, rho_pred_min, tau_aer, rho_aer) != 0)
2964 for (iw = 0; iw < nwave; iw++) {
2965 rhoa[iw] = rho_aer[iw];
2980 int32_t iwnir_l, int32_t nmodels, int32_t mindx[], geom_str *
geom,
2981 float wv,
float rhoa[], int32_t *modmin, int32_t *modmax,
2982 float *modrat,
float *epsnir,
float tauamin[],
float tauamax[]) {
2998 if ((rhoasmin = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
2999 printf(
"Unable to allocate space for rhoasmin.\n");
3002 if ((rhoasmax = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
3003 printf(
"Unable to allocate space for rhoasmax.\n");
3006 if ((rhoamin = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
3007 printf(
"Unable to allocate space for rhoamin.\n");
3010 if ((rhoamax = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
3011 printf(
"Unable to allocate space for rhoasmax.\n");
3017 rhoa, iwnir_s, iwnir_l, modmin, modmax, modrat, epsnir);
3021 cc = log(*epsnir) / (wave[iwnir_l] - wave[iwnir_s]);
3043 for (iw = 0; iw < nwave; iw++) {
3045 epsmin1 = epsmin[iw];
3046 epsmax1 = epsmax[iw];
3049 epsmin1 = exp(cc * (wave[iwnir_l] - wave[iw]));
3053 rhoasmin[iw] = rhoasmin[iwnir_l] * epsmin1;
3054 rhoasmax[iw] = rhoasmax[iwnir_l] * epsmax1;
3062 for (iw = 0; iw < nwave; iw++) {
3063 rhoa[iw] = rhoamin[iw]*(1.0 - (*modrat)) + rhoamax[iw]*(*modrat);
3091 return (
x->rhoa <
y->rhoa ? -1 : 1);
3095 int32_t nmodel, int32_t mindx[], geom_str *
geom,
float wv,
3096 float rhoa[], int32_t iwnir_s, int32_t iwnir_l, int32_t *modmin,
3097 int32_t *modmax,
float *modrat,
float *epsnir) {
3113 if ((rhoas = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
3114 printf(
"Unable to allocate space for rhoas.\n");
3117 if ((rhoa_tmp = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
3118 printf(
"Unable to allocate space for rhoas_tmp.\n");
3124 for (jm = 0; jm < nmodel; jm++) {
3138 rhoas[iwnir_s] = rhoas[iwnir_l] * eps[iwnir_s];
3143 rhoa_tab[jm].modnum =
im;
3144 rhoa_tab[jm].rhoa = rhoa_tmp[iwnir_s];
3145 rhoa_tab[jm].eps = eps[iwnir_s];
3149 qsort(rhoa_tab, nmodel,
sizeof (rhoaTstr), (
int (*)(
const void *,
const void *))
comp_rhoaT);
3152 for (jm = 0; jm < nmodel; jm++) {
3153 if (rhoa_tab[jm].rhoa > rhoa[iwnir_s])
3159 }
else if (jm == nmodel) {
3166 wt = (rhoa[iwnir_s] - rhoa_tab[jm1].rhoa) / (rhoa_tab[jm2].rhoa - rhoa_tab[jm1].rhoa);
3168 *modmin = rhoa_tab[jm1].modnum;
3169 *modmax = rhoa_tab[jm2].modnum;
3171 *epsnir = rhoa_tab[jm1].eps * (1.0 - wt) + rhoa_tab[jm2].eps*wt;
3184 static int order_models(
const void *
p1,
const void *p2) {
3185 aermodstr *
x = *(aermodstr **)
p1;
3186 aermodstr *
y = *(aermodstr **) p2;
3188 if (
x->rh ==
y->rh) {
3206 int rhaer(int32_t
sensorID,
float wave[], int32_t nwave, int32_t iwnir_s, int32_t iwnir_l,
3207 geom_str *
geom,
float wv,
float rh,
float pr,
float taur[],
float rhoa[],
3208 int32_t *modmin1, int32_t *modmax1,
float *modrat1, int32_t *modmin2, int32_t *modmax2,
float *modrat2,
3209 float *eps,
float taua[],
float tsol[],
float tsen[],
float tg_sol_sm[],
float tg_sen_sm[],
float Lt_sm[], int32_t ip) {
3210 static int firstCall = 1;
3229 float *tau_pred_min1;
3230 float *tau_pred_max1;
3231 float *tau_pred_min2;
3232 float *tau_pred_max2;
3241 int irh1, irh2, irh;
3251 float lastrh = -1.0;
3254 printf(
"-E- %s line %d: This aerosol selection method requires models with a Relative Humidity attribute and size distribution.\n",
3255 __FILE__, __LINE__);
3260 qsort(aertab->model, aertab->nmodel, sizeof (aermodstr*), (
int (*)(
const void *,
const void *)) order_models);
3268 for (
im = 0;
im < aertab->nmodel;
im++) {
3269 if (aertab->model[
im]->rh != lastrh) {
3270 rhtab[nrh] = aertab->model[
im]->rh;
3271 lastrh = rhtab[nrh];
3274 if (nrh == 1 && aertab->model[
im]->sd != lastsd) {
3275 sdtab[nsd] = aertab->model[
im]->sd;
3276 lastsd = sdtab[nsd];
3280 if (nrh * nsd != aertab->nmodel) {
3281 printf(
"-E- %s line %d: number of humidities (%d) x number of size distributions (%d) must equal number of models (%d).\n",
3282 __FILE__, __LINE__, nrh, nsd, aertab->nmodel);
3285 printf(
"%d aerosol models: %d humidities x %d size fractions\n", aertab->nmodel, nrh, nsd);
3286 for (irh = 0; irh < nrh; irh++) {
3287 for (isd = 0; isd < nsd; isd++) {
3288 im = irh * nsd + isd;
3289 printf(
"model %d, rh=%f, sd=%d, alpha=%f, name=%s\n",
3290 im, aertab->model[
im]->rh, aertab->model[
im]->sd, aertab->model[
im]->angstrom[1], aertab->model[
im]->name);
3297 if ((taua1 = (
float *) malloc(nwave *
sizeof (
float))) ==
NULL) {
3298 printf(
"Unable to allocate space for taua1.\n");
3301 if ((taua2 = (
float *) malloc(nwave *
sizeof (
float))) ==
NULL) {
3302 printf(
"Unable to allocate space for taua2.\n");
3305 if ((tsol1 = (
float *) malloc(nwave *
sizeof (
float))) ==
NULL) {
3306 printf(
"Unable to allocate space for tsol1.\n");
3309 if ((tsol2 = (
float *) malloc(nwave *
sizeof (
float))) ==
NULL) {
3310 printf(
"Unable to allocate space for tsol2.\n");
3313 if ((rhoa1 = (
float *) malloc(nwave *
sizeof (
float))) ==
NULL) {
3314 printf(
"Unable to allocate space for rhoa1.\n");
3317 if ((rhoa2 = (
float *) malloc(nwave *
sizeof (
float))) ==
NULL) {
3318 printf(
"Unable to allocate space for rhoa2.\n");
3321 if ((tsen1 = (
float *) malloc(nwave *
sizeof (
float))) ==
NULL) {
3322 printf(
"Unable to allocate space for tsen1.\n");
3325 if ((tsen2 = (
float *) malloc(nwave *
sizeof (
float))) ==
NULL) {
3326 printf(
"Unable to allocate space for tsen2.\n");
3329 if ((tau_pred_min1 = (
float *) malloc(nwave *
sizeof (
float))) ==
NULL) {
3330 printf(
"Unable to allocate space for tau_pred_min1.\n");
3333 if ((tau_pred_min2 = (
float *) malloc(nwave *
sizeof (
float))) ==
NULL) {
3334 printf(
"Unable to allocate space for tau_pred_min2.\n");
3337 if ((tau_pred_max1 = (
float *) malloc(nwave *
sizeof (
float))) ==
NULL) {
3338 printf(
"Unable to allocate space for tau_pred_max1.\n");
3341 if ((tau_pred_max2 = (
float *) malloc(nwave *
sizeof (
float))) ==
NULL) {
3342 printf(
"Unable to allocate space for tau_pred_max2.\n");
3353 for (iw = 0; iw < nwave; iw++) {
3357 rhoa1[iw] = rhoa[iw];
3358 rhoa2[iw] = rhoa[iw];
3366 printf(
"Warning rh is greater than 95%%. Reset to 94%% rh=%f\n", rh);
3372 if (nrh == 1 || rhtab[0] > rh) {
3376 }
else if (rhtab[nrh - 1] < rh) {
3381 for (irh = 0; irh < nrh; irh++) {
3382 if (rhtab[irh] > rh)
3385 irh1 =
MIN(
MAX(0, irh - 1), nrh - 2);
3387 wt = (rh - rhtab[irh1]) / (rhtab[irh2] - rhtab[irh1]);
3391 if (rh - rhtab[irh1] <= (rhtab[irh2] - rhtab[irh1]) / 2)
3402 for (
im = 0;
im < nsd;
im++) {
3403 mindx3[
im] = irh3 * nsd +
im;
3408 for (
im = 0;
im < nsd;
im++) {
3409 mindx1[
im] = irh1 * nsd +
im;
3410 mindx2[
im] = irh2 * nsd +
im;
3421 if (mindx3[0] == mindx1[0] || mindx3[0] == mindx2[0] || mindx3[0] > 79 || mindx3[0] < 0)
3424 else if (mindx1[0] == mindx2[0])
3427 int32_t vcal_flag = 1;
3428 if ((aertab->nmodel) == vcal_flag)
3434 float rho_aer[nwave];
3437 if (
smaer(
sensorID, wave, nwave, iwnir_s, iwnir_l, nmodels, mindx1, mindx1, mindx1,
3438 geom, wv, rhoa1, rho_aer, &modmin, &modmax, &modrat, tau_pred_min1, tau_pred_max1, tg_sol_sm, tg_sen_sm, Lt_sm, ip) == 0) {
3450 *modmin1, *modmax1, *modrat1, rhoa1, taua1, tsol1, tsen1, tau_pred_min1, tau_pred_max1, 1);
3453 if (
smaer(
sensorID, wave, nwave, iwnir_s, iwnir_l, nmodels, mindx2, mindx2, mindx2,
3454 geom, wv, rhoa2, rho_aer, &modmin, &modmax, &modrat, tau_pred_min2, tau_pred_max2, tg_sol_sm, tg_sen_sm, Lt_sm, ip) == 0) {
3466 *modmin2, *modmax2, *modrat2, rhoa2, taua2, tsol2, tsen2, tau_pred_min2, tau_pred_max2, 1);
3477 free(tau_pred_min1);
3478 free(tau_pred_max1);
3479 free(tau_pred_min2);
3480 free(tau_pred_max2);
3485 geom, wv, rhoa1, modmin1, modmax1, modrat1, &eps1, tau_pred_min1, tau_pred_max1) != 0) {
3494 free(tau_pred_min1);
3495 free(tau_pred_max1);
3496 free(tau_pred_min2);
3497 free(tau_pred_max2);
3503 geom, wv, rhoa1, modmin1, modmax1, modrat1, &eps1, tau_pred_min1, tau_pred_max1) != 0) {
3512 free(tau_pred_min1);
3513 free(tau_pred_max1);
3514 free(tau_pred_min2);
3515 free(tau_pred_max2);
3522 *modmin1, *modmax1, *modrat1, rhoa1, taua1, tsol1, tsen1, tau_pred_min1, tau_pred_max1, 1);
3529 for (iw = 0; iw < nwave; iw++) {
3530 rhoa[iw] = rhoa1[iw]*(1 - wt) + rhoa2[iw] * wt;
3531 taua[iw] = taua1[iw]*(1 - wt) + taua2[iw] * wt;
3532 tsol[iw] = tsol1[iw]*(1 - wt) + tsol2[iw] * wt;
3533 tsen[iw] = tsen1[iw]*(1 - wt) + tsen2[iw] * wt;
3541 geom, wv, rhoa2, modmin2, modmax2, modrat2, &eps2, tau_pred_min2, tau_pred_max2) != 0) {
3550 free(tau_pred_min1);
3551 free(tau_pred_max1);
3552 free(tau_pred_min2);
3553 free(tau_pred_max2);
3558 geom, wv, rhoa2, modmin2, modmax2, modrat2, &eps2, tau_pred_min2, tau_pred_max2) != 0) {
3567 free(tau_pred_min1);
3568 free(tau_pred_max1);
3569 free(tau_pred_min2);
3570 free(tau_pred_max2);
3576 *modmin2, *modmax2, *modrat2, rhoa2, taua2, tsol2, tsen2, tau_pred_min2, tau_pred_max2, 1);
3578 for (iw = 0; iw < nwave; iw++) {
3579 rhoa[iw] = rhoa1[iw]*(1 - wt) + rhoa2[iw] * wt;
3580 taua[iw] = taua1[iw]*(1 - wt) + taua2[iw] * wt;
3581 tsol[iw] = tsol1[iw]*(1 - wt) + tsol2[iw] * wt;
3582 tsen[iw] = tsen1[iw]*(1 - wt) + tsen2[iw] * wt;
3584 *eps = eps1 * (1 - wt) + eps2*wt;
3588 for (iw = 0; iw < nwave; iw++) {
3589 rhoa[iw] = rhoa1[iw];
3590 taua[iw] = taua1[iw];
3591 tsol[iw] = tsol1[iw];
3592 tsen[iw] = tsen1[iw];
3617 free(tau_pred_min1);
3618 free(tau_pred_max1);
3619 free(tau_pred_min2);
3620 free(tau_pred_max2);
3632 int fixedaer(int32_t
sensorID, int32_t modnum,
float wave[], int32_t nwave, int32_t iwnir_s, int32_t iwnir_l,
3633 char models[
MAXAERMOD][32], int32_t nmodels,
3634 geom_str *
geom,
float wv,
float rhoa[],
float *epsnir) {
3639 if ((rhoas = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
3640 printf(
"Unable to allocate space for rhoas.\n");
3644 if (rhoa[iwnir_l] < 0.0) {
3657 printf(
"Error getting rhoas\n");
3663 for (iw = 0; iw < nwave; iw++) {
3664 rhoas[iw] = rhoas[iwnir_l] * eps[iw];
3670 if (iwnir_s == iwnir_l)
3671 *epsnir = eps[iwnir_l - 1];
3673 *epsnir = eps[iwnir_s];
3688 int32_t iwnir_s, int32_t iwnir_l, geom_str *
geom,
float wv,
3689 int32_t modmin, int32_t modmax,
float modrat,
float rhoa[],
float *eps) {
3697 if ((rhoa1 = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
3698 printf(
"Unable to allocate space for rhoa1.\n");
3701 if ((rhoa2 = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
3702 printf(
"Unable to allocate space for rhoa2.\n");
3706 if (modmin < 0 || modmin >=
input->naermodels ||
3707 modmax < 0 || modmax >=
input->naermodels ||
3708 modrat < 0.0 || modrat > 1.0) {
3709 printf(
"Bogus input for fixed model pair: %d %d %f\n", modmin + 1, modmax + 1, modrat);
3714 if (rhoa[iwnir_l] >
input->rhoamin) {
3716 rhoa2[iwnir_l] = rhoa1[iwnir_l] = rhoa[iwnir_l];
3726 for (iw = 0; iw < nwave; iw++) {
3728 rhoa[iw] =
MAX((1.0 - modrat) * rhoa1[iw] + modrat * rhoa2[iw], 0.0);
3730 *eps = (1.0 - modrat) * eps1 + modrat*eps2;
3733 }
else if (rhoa[iwnir_l] > -(
input->rhoamin)) {
3737 for (iw = 0; iw < nwave; iw++) {
3738 rhoa[iw] =
MAX(rhoa[iwnir_l], 1e-6);
3764 int32_t iwnir_s, int32_t iwnir_l, geom_str *
geom,
float wv,
3765 int32_t *modmin, int32_t *modmax,
float *modrat,
float rhoa[],
3767 static int firstCall = 1;
3768 static int angst_band1 = -1;
3769 static int angst_band2 = -1;
3784 int ig, gmult, iw, iwtab;
3787 maxwave =
MAX(aertab->nwave, nwave);
3789 if ((rhoa1 = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
3790 printf(
"Unable to allocate space for rhoa1.\n");
3793 if ((rhoa2 = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
3794 printf(
"Unable to allocate space for rhoa2.\n");
3797 if ((rhoas1 = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
3798 printf(
"Unable to allocate space for rhoas1.\n");
3801 if ((rhoas2 = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
3802 printf(
"Unable to allocate space for rhoas2.\n");
3805 if ((
f1 = (
float *) calloc(maxwave,
sizeof (
float))) ==
NULL) {
3806 printf(
"Unable to allocate space for f1.\n");
3809 if ((
f2 = (
float *) calloc(maxwave,
sizeof (
float))) ==
NULL) {
3810 printf(
"Unable to allocate space for f2.\n");
3813 if ((lnf1 = (
float *) calloc(maxwave,
sizeof (
float))) ==
NULL) {
3814 printf(
"Unable to allocate space for lnf1.\n");
3817 if ((lnf2 = (
float *) calloc(maxwave,
sizeof (
float))) ==
NULL) {
3818 printf(
"Unable to allocate space for lnf2.\n");
3823 angst_band1 =
windex(520, wave, nwave);
3824 angst_band2 =
windex(865, wave, nwave);
3829 for (iw = 0; iw < nwave; iw++) {
3830 if (aot[iw] < 0.0) {
3844 if (aot[iwnir_l] > 0.0)
3845 angstrom = -log(aot[angst_band1] / aot[angst_band2]) /
3846 log(wave[angst_band1] / wave[angst_band2]);
3857 gmult = (interpol == 1) ? 0 :
geom->gmult;
3860 for (iw = 0; iw < aertab->nwave; iw++) {
3862 f1[iw] = aertab->model[*modmin]->albedo[iw] *
3863 phase1[iw] / 4.0 /
geom->csolz[ig] /
geom->csenz[ig];
3864 f2[iw] = aertab->model[*modmax]->albedo[iw] *
3865 phase2[iw] / 4.0 /
geom->csolz[ig] /
geom->csenz[ig];
3867 lnf1[iw] = log(
f1[iw]);
3868 lnf2[iw] = log(
f2[iw]);
3874 for (iw = 0; iw < nwave; iw++) {
3876 if (aertab->wave[iwtab] != wave[iw] && wave[iw] > 0) {
3877 rhoas1[iw] = aot[iw] * exp(
linterp(aertab->wave, lnf1, aertab->nwave, wave[iw]));
3878 rhoas2[iw] = aot[iw] * exp(
linterp(aertab->wave, lnf2, aertab->nwave, wave[iw]));
3880 rhoas1[iw] = aot[iw] *
f1[iwtab];
3881 rhoas2[iw] = aot[iw] *
f2[iwtab];
3885 for (iw = 0; iw < nwave; iw++) {
3887 rhoas1[iw] = aot[iw] *
f1[iwtab];
3888 rhoas2[iw] = aot[iw] *
f2[iwtab];
3891 eps1 = rhoas1[iwnir_s] / rhoas1[iwnir_l];
3892 eps2 = rhoas2[iwnir_s] / rhoas2[iwnir_l];
3898 for (iw = 0; iw < nwave; iw++) {
3899 rhoa[iw] = (1.0 - *modrat) * rhoa1[iw] + *modrat * rhoa2[iw];
3901 *epsnir = (1.0 - *modrat) * eps1 + *modrat * eps2;
3922 int aerosol(l2str *l2rec, int32_t aer_opt_in, aestr *aerec, int32_t ip,
3923 float wave[], int32_t nwave, int32_t iwnir_s_in, int32_t iwnir_l_in,
3924 float F0_in[],
float La1_in[],
float La2_out[],
3925 float t_sol_out[],
float t_sen_out[],
float *eps,
float taua_out[],
3926 int32_t *modmin, int32_t *modmax,
float *modrat,
3927 int32_t *modmin2, int32_t *modmax2,
float *modrat2) {
3928 static int firstCall = 1;
3947 float *taua_pred_min;
3948 float *taua_pred_max;
3950 l1str *
l1rec = l2rec->l1rec;
3952 float *tg_sol_sm = l2rec->l1rec->tg_sol;
3953 float *tg_sen_sm = l2rec->l1rec->tg_sen;
3954 float *Lt_sm = l2rec->l1rec->Lt;
3959 float wv =
l1rec->wv [ip];
3960 float rh =
l1rec->rh [ip];
3964 if (firstCall == 1) {
3966 Maxband = nwave + 1;
3969 if ((rhoa = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
3970 printf(
"Unable to allocate space for rhoa.\n");
3973 if ((radref = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
3974 printf(
"Unable to allocate space for raderef.\n");
3977 if ((
F0 = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
3978 printf(
"Unable to allocate space for F0.\n");
3981 if ((taur = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
3982 printf(
"Unable to allocate space for taur.\n");
3985 if ((La1 = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
3986 printf(
"Unable to allocate space for La1.\n");
3989 if ((La2 = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
3990 printf(
"Unable to allocate space for La2.\n");
3993 if ((t_sol = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
3994 printf(
"Unable to allocate space for t_sol.\n");
3997 if ((t_sen = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
3998 printf(
"Unable to allocate space for t_sen.\n");
4001 if ((taua = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
4002 printf(
"Unable to allocate space for taua.\n");
4005 if ((taua_pred_min = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
4006 printf(
"Unable to allocate space for taua_pred_min.\n");
4009 if ((taua_pred_max = (
float *) calloc(nwave,
sizeof (
float))) ==
NULL) {
4010 printf(
"Unable to allocate space for taua_pred_max.\n");
4024 geom.airmass = (
float *) malloc(
sizeof (
float));
4025 *
geom.airmass = 1. /
geom.csolz[0] + 1. /
geom.csenz[0];
4027 geom.airmass_sph = (
float *) malloc(
sizeof (
float));
4028 geom.airmass_plp = (
float *) malloc(
sizeof (
float));
4036 geom.senz = &
l1rec->geom_per_band->senz[ipb];
4037 geom.solz = &
l1rec->geom_per_band->solz[ipb];
4038 geom.phi = &
l1rec->geom_per_band->delphi[ipb];
4039 geom.csolz = &
l1rec->geom_per_band->csolz[ipb];
4040 geom.csenz = &
l1rec->geom_per_band->csenz[ipb];
4043 geom.airmass = (
float *) malloc(
Nbands *
sizeof (
float));
4044 for (iw = 0; iw <
Nbands; iw++) {
4045 geom.airmass[iw] = 1. /
geom.csolz[iw] + 1. /
geom.csenz[iw];
4048 geom.airmass_plp = (
float *) malloc(
Nbands *
sizeof (
float));
4049 geom.airmass_sph = (
float *) malloc(
Nbands *
sizeof (
float));
4050 for (iw = 0; iw <
Nbands; iw++) {
4061 aer_opt = aer_opt_in;
4064 for (iw = 0; iw < nwave; iw++) {
4065 F0 [iw] = F0_in [iw];
4066 taur[iw] =
l1rec->l1file->Tau_r[iw];
4067 La1 [iw] = La1_in[iw];
4068 if (iw == iwnir_s_in) iwnir_s = iw;
4069 if (iw == iwnir_l_in) iwnir_l = iw;
4073 mu0 = cos(
solz / radeg);
4074 mu = cos(
senz / radeg);
4075 airmass = 1.0 / mu0 + 1.0 / mu;
4089 for (iw = 0; iw < nwave; iw++) {
4094 radref[iw] =
pi /
F0[iw] /
geom.csolz[iw *
geom.gmult];
4101 for (
im = 0;
im < aertab->nmodel;
im++) mindx[
im] =
im;
4102 if (have_rh && aertab->nmodel >= 30) {
4103 printf(
"\nLimiting aerosol models based on RH.\n");
4110 if ((interpol == 1) && (
geom.gmult == 1)) {
4111 fprintf(
stderr,
"-E- %s line %d: Interpolated aerosol tables are\n",
4112 __FILE__, __LINE__);
4113 fprintf(
stderr,
" not permitted for use with band-dependent geometry, set geom_per_band=0\n");
4132 if (aer_opt > 0 && aer_opt <=
MAXAERMOD) {
4133 printf(
"\nUsing fixed aerosol model #%d (%s)\n", aer_opt,
input->aermodels[aer_opt - 1]);
4134 printf(
"Extrapolating from %4.1f nm\n", wave[iwnir_l]);
4138 printf(
"\nUsing Spectral Matching of aerosols reflectance for\n");
4139 printf(
"wavelength from %4.1f nm to %4.1f nm for model selection\n", wave[iwnir_s], wave[iwnir_l]);
4142 printf(
"\nUsing white-aerosol approximation\n");
4143 printf(
"Extrapolating from %4.1f nm\n", wave[iwnir_l]);
4147 printf(
"\nUsing Gordon & Wang aerosol model selection\n");
4148 printf(
"Using bands at %4.1f and %4.1f nm for model selection\n", wave[iwnir_s], wave[iwnir_l]);
4149 printf(
"Extrapolating from %4.1f nm\n", wave[iwnir_l]);
4153 printf(
"\nUsing Gordon & Wang aerosol model selection\n");
4154 printf(
" and NIR correction with up to %d iterations\n",
input->aer_iter_max);
4155 printf(
"Using bands at %4.1f and %4.1f nm for model selection\n", wave[iwnir_s], wave[iwnir_l]);
4156 printf(
"Extrapolating from %4.1f nm\n", wave[iwnir_l]);
4160 printf(
"\nUsing Gordon & Wang aerosol model selection with NIR/SWIR switching.\n");
4161 printf(
"NIR correction with up to %d iterations\n",
input->aer_iter_max);
4162 printf(
"NIR bands at %d and %d nm\n",
input->aer_wave_short,
input->aer_wave_long);
4163 printf(
"SWIR bands at %d and %d nm\n\n",
input->aer_swir_short,
input->aer_swir_long);
4167 printf(
"\nUsing Gordon & Wang aerosol model selection\n");
4168 printf(
" and MUMM correction\n");
4169 printf(
"Using bands at %4.1f and %4.1f nm for model selection\n", wave[iwnir_s], wave[iwnir_l]);
4170 printf(
"Extrapolating from %4.1f nm\n", wave[iwnir_l]);
4173 printf(
"\nUsing multi-scattering aerosol model selection.\n");
4174 printf(
" and NIR correction with up to %d iterations\n",
input->aer_iter_max);
4175 printf(
"Using bands at %4.1f and %4.1f nm for model selection\n", wave[iwnir_s], wave[iwnir_l]);
4176 printf(
"Extrapolating from %4.1f nm\n", wave[iwnir_l]);
4179 printf(
"\nUsing multi-scattering aerosol model selection in linear space.\n");
4180 printf(
" and NIR correction with up to %d iterations\n",
input->aer_iter_max);
4181 printf(
"Using bands at %4.1f and %4.1f nm for model selection\n", wave[iwnir_s], wave[iwnir_l]);
4182 printf(
"Extrapolating from %4.1f nm\n", wave[iwnir_l]);
4185 printf(
"\nUsing fixed, input aerosol optical thicknesses for aerosol selection.\n");
4188 printf(
"\nUsing multiple scattering aerosols with fixed model pair\n");
4191 printf(
"\nUsing multiple scattering aerosols with fixed model pair\n");
4192 printf(
" and NIR iteration with up to %d iterations\n",
input->aer_iter_max);
4193 printf(
"Extrapolating from %4.1f nm\n", wave[iwnir_l]);
4196 printf(
"\nUsing fixed aerosol model based on predefined Angstrom exponent\n");
4197 printf(
"Extrapolating from %4.1f nm\n", wave[iwnir_l]);
4200 printf(
"\nUsing fixed aerosol model based on predefined Angstrom exponent\n");
4201 printf(
" and NIR iteration with up to %d iterations\n",
input->aer_iter_max);
4202 printf(
"Extrapolating from %4.1f nm\n", wave[iwnir_l]);
4205 printf(
"\nErroneous aerosol option, %d\n", aer_opt);
4215 for (iw = iwnir_s; iw <= iwnir_l; iw +=
MAX(iwnir_l - iwnir_s, 1))
4216 rhoa[iw] = La1[iw] * radref[iw];
4226 if (iwnir_l <= iwnir_s || wave[iwnir_s] < 600) {
4227 printf(
"Aerosol selection bands must be greater than 600nm with short wave less than long wave (%d,%d)\n", iwnir_l, iwnir_s);
4235 for (iw = iwnir_s; iw <= iwnir_l; iw++) {
4236 rhoa[iw] = La1[iw] * radref[iw];
4240 if (rhoa[iwnir_s] >
input->rhoamin && rhoa[iwnir_l] >
input->rhoamin) {
4243 if (La1[iwnir_s] / La1[iwnir_l] > 0.1) {
4246 aertab->nmodel, mindx,
4247 &
geom, wv, rhoa, modmin, modmax, modrat, eps, taua, taua);
4250 for (iw = 0; iw < nwave; iw++)
4251 La2[iw] = rhoa[iw] / radref[iw];
4254 }
else if (rhoa[iwnir_s] > -(
input->rhoamin) && rhoa[iwnir_l] > -(
input->rhoamin)) {
4258 *modmin = aertab->nmodel;
4259 *modmax = aertab->nmodel;
4261 temp =
MAX(rhoa[iwnir_l], 1e-6);
4262 for (iw = 0; iw < nwave; iw++) {
4264 La2 [iw] = rhoa[iw] / radref[iw];
4285 if (iwnir_l <= iwnir_s || wave[iwnir_s] < 600) {
4286 printf(
"Aerosol selection bands must be greater than 600nm with short wave less than long wave");
4294 for (iw = iwnir_s; iw <= iwnir_l; iw++) {
4295 rhoa[iw] = La1[iw] * radref[iw];
4299 if (rhoa[iwnir_s] >
input->rhoamin && rhoa[iwnir_l] >
input->rhoamin) {
4302 if (rhoa[iwnir_s] / rhoa[iwnir_l] > 0.1 && rhoa[iwnir_s] / rhoa[iwnir_l] < 10.0) {
4305 &
geom, wv, rh,
pr, taur, rhoa,
4306 modmin, modmax, modrat, modmin2, modmax2, modrat2, eps, taua, t_sol, t_sen, tg_sol_sm, tg_sen_sm, Lt_sm, ip);
4309 for (iw = 0; iw < nwave; iw++)
4310 La2[iw] = rhoa[iw] / radref[iw];
4313 }
else if (rhoa[iwnir_s] > -(
input->rhoamin) && rhoa[iwnir_l] > -(
input->rhoamin)) {
4317 *modmin = aertab->nmodel;
4318 *modmax = aertab->nmodel;
4320 *modmin2 = aertab->nmodel;
4321 *modmax2 = aertab->nmodel;
4323 temp =
MAX(rhoa[iwnir_l], 1e-6);
4324 for (iw = 0; iw < nwave; iw++) {
4326 La2 [iw] = rhoa[iw] / radref[iw];
4340 *modmin, *modmax, *modrat, rhoa, taua, t_sol, t_sen, taua_pred_min, taua_pred_max, taua_opt);
4357 if (La1[iwnir_l] > 0.0) {
4364 for (iw = 0; iw < nwave; iw++) {
4365 La2 [iw] = *eps *
F0[iw] /
F0[iwnir_l] * La1[iwnir_l];
4366 rhoa[iw] = La2[iw] * radref[iw];
4379 if (aerec !=
NULL && aerec->mode ==
ON) {
4380 *modmin = aerec->mod_min[ip] - 1;
4381 *modmax = aerec->mod_max[ip] - 1;
4382 *modrat = aerec->mod_rat[ip];
4384 *modmin =
input->aermodmin - 1;
4385 *modmax =
input->aermodmax - 1;
4386 *modrat =
input->aermodrat;
4390 *modmin, *modmax, *modrat, rhoa, eps);
4392 for (iw = 0; iw < nwave; iw++)
4393 La2[iw] = rhoa[iw] / radref[iw];
4400 if (
input->aer_angstrom > -2) {
4401 angstrom =
input->aer_angstrom;
4409 if (angstrom > -2) {
4414 *modmin, *modmax, *modrat, rhoa, eps);
4419 for (iw = 0; iw < nwave; iw++)
4420 La2[iw] = rhoa[iw] / radref[iw];
4429 if (aerec !=
NULL && aerec->mode ==
ON)
4430 aot = &aerec->taua[ip *
Nbands];
4435 modmin, modmax, modrat, rhoa, eps);
4437 for (iw = 0; iw < nwave; iw++)
4438 La2[iw] = rhoa[iw] / radref[iw];
4448 *modmin = aer_opt - 1;
4449 *modmax = aer_opt - 1;
4452 if (*modmin < 0 || *modmin >
input->naermodels - 1) {
4453 printf(
"Invalid aerosol option: %d\n", *modmin);
4458 rhoa[iwnir_l] = La1[iwnir_l] * radref[iwnir_l];
4463 &
geom, wv, rhoa, eps);
4467 for (iw = 0; iw < nwave; iw++)
4468 La2[iw] = rhoa[iw] / radref[iw];
4476 *modmin, *modmax, *modrat, rhoa, taua, t_sol, t_sen, taua_pred_min, taua_pred_max, 0);
4480 for (iw = 0; iw < nwave; iw++) {
4481 La2_out [iw] = La2 [iw];
4482 taua_out [iw] = taua [iw];
4483 t_sol_out[iw] = t_sol[iw];
4484 t_sen_out[iw] = t_sen[iw];
4488 *modmin = *modmin + 1;
4489 *modmax = *modmax + 1;
4490 *modmin2 = *modmin2 + 1;
4491 *modmax2 = *modmax2 + 1;
4502 free(taua_pred_min);
4503 free(taua_pred_max);
4506 free(
geom.airmass_plp);
4507 free(
geom.airmass_sph);
4530 static int firstCall = 1;
4540 l1str *
l1rec = l2rec->l1rec;
4545 wave2 =
l1file->fwave[ib2];
4553 wave1 =
l1file->fwave[ib1];
4555 for (ip = 0; ip <
l1rec->npix; ip++) {
4556 aot1 = l2rec->taua[ip *
l1file->nbands + ib1];
4557 aot2 = l2rec->taua[ip *
l1file->nbands + ib2];
4558 if (aot1 > 0.0 && aot2 > 0.0)
4559 angst[ip] = -log(aot1 / aot2) / log(wave1 / wave2);
4560 else if (aot1 == 0.0 && aot2 == 0.0)
4578 int32_t ip, ipb1, ipb2;
4580 l1str *
l1rec = l2rec->l1rec;
4583 for (ip = 0; ip <
l1rec->npix; ip++) {
4584 ipb1 = ip *
l1file->nbands + iwnir_s;
4585 ipb2 = ip *
l1file->nbands + iwnir_l;
4586 if (l2rec->La[ipb2] > 0.0) {
4587 eps[ip] = l2rec->La[ipb1] / l2rec->La[ipb2]