35 #include <gsl/gsl_rng.h>
36 #include <gsl/gsl_randist.h>
44 return (tv.tv_sec + tv.tv_usec);
51 rng = gsl_rng_alloc(gsl_rng_mt19937);
52 gsl_rng_set(rng, randSeed);
53 noise = gsl_ran_gaussian(rng, sigma);
65 static int firstpassperband = 0;
67 float sigma, noise, snr, scaled_lt;
68 float ltSnrFitCoef[16][2] = {
69 {0.05499859, 0.00008340},
70 {0.02939470, 0.00009380},
71 {0.11931482, 0.00008195},
72 {0.01927545, 0.00009450},
73 {0.01397522, 0.00010040},
74 {0.01139088, 0.00016480},
75 {0.08769538, 0.00007000},
76 {0.10406925, 0.00008533},
77 {0.00496291, 0.00014050},
78 {0.00427147, 0.00013160},
79 {0.00416994, 0.00021250},
80 {0.04055895, 0.00019755},
81 {0.00312263, 0.00018600},
82 {0.07877732, 0.00049940},
83 {0.26743281, 0.01044864},
84 {0.00628912, 0.00021160}
87 noise = ltSnrFitCoef[iw][0] + ltSnrFitCoef[iw][1] * scaled_lt;
88 snr = scaled_lt * snr_mult / noise;
90 if (firstpassperband == iw) {
91 printf(
"Band: %d - Lt=%f - Sigma=%f\n", iw, lt, sigma);
99 static int firstpassperband = 0;
101 int i, fitPolyOrder = 4;
103 float ltSnrFitCoef[8][5] = {
104 {-8.28726301e-03, 3.85425664e-01, -9.10776926e+00, 1.65881862e+02, 4.54351582e-01},
105 {-1.21871258e-02, 5.21579320e-01, -1.14574109e+01, 1.96509056e+02, 4.18921861e-01},
106 {-2.99068165e-02, 1.05225457e-00, -1.90591166e+01, 2.66343986e+02, 6.67187489e-01},
107 {-5.68939986e-02, 1.67950509e-00, -2.56915149e+01, 3.05832773e+02, 9.34468454e-01},
108 {-1.31635902e-01, 3.09617393e-00, -3.73473556e+01, 3.52394751e+02, 3.54105899e-01},
109 {-8.65458303e-01, 1.18857306e+01, -8.37771886e+01, 4.64496430e+02, 4.14633422e-02},
110 {-4.96827099e+00, 4.50239057e+01, -2.10425126e+02, 7.75862055e+02, 5.18893137e-02},
111 {-1.30487418e+01, 9.35407901e+01, -3.40988182e+02, 9.43414239e+02, 7.84956550e-01}
127 for (
i = 0;
i < fitPolyOrder;
i++)
128 snr += ltSnrFitCoef[iw][
i] * pow(lt, (fitPolyOrder -
i));
129 snr += ltSnrFitCoef[iw][fitPolyOrder];
132 if (firstpassperband == iw) {
133 printf(
"Band: %d - Lt=%f - Sigma=%f\n", iw, lt, sigma);
154 printf(
"-E-: %s line %d: Sensor not supported.\n", __FILE__, __LINE__);
184 float get_anc_noise(
float anc_unc,
float anc_data,
float inp_factor,
char anc_name[20]) {
185 static int printPass = 0;
187 float noise, sigma = 0;
188 if (inp_factor == 0.0)
189 sigma =
fabs(anc_unc / anc_data / sqrt(2));
190 else if (inp_factor > 0.0)
191 sigma =
fabs(inp_factor * anc_unc / anc_data / sqrt(2));
193 if ((printPass % 1000000) == 0) {
194 printf(
"ANCNOISE=>%d: anc_name=%s|-|anc_unc=%f|-|anc_data=%f|-|inp-fac=%f|-|sigma=%f|-|noise=%f \n",
195 printPass, anc_name, anc_unc, anc_data, inp_factor, sigma, noise);
196 printPass += 1000000;
202 static double radeg =
RADEG;
208 int32_t ip, ipb, ib, iw, ix;
214 float lt_noise =
input->add_lt_noise;
215 float ws_noise =
input->add_ws_noise;
216 float wd_noise =
input->add_wd_noise;
217 float mw_noise =
input->add_mw_noise;
218 float zw_noise =
input->add_zw_noise;
219 float rh_noise =
input->add_rh_noise;
220 float pr_noise =
input->add_pr_noise;
221 float wv_noise =
input->add_wv_noise;
222 float oz_noise =
input->add_oz_noise;
223 float no2_tropo_noise =
input->add_no2_tropo_noise;
224 float no2_strat_noise =
input->add_no2_strat_noise;
227 static int firstpassperband = 0;
239 printf(
"Loading land mask information from %s\n",
input->land);
241 printf(
"-E- %s : Unable to initialize land mask\n", __FILE__);
245 printf(
"Loading DEM information from %s\n",
input->demfile);
246 if (
input->dem_auxfile[0])
247 printf(
"Loading auxiliary elevation file from %s\n",
input->dem_auxfile);
249 printf(
"-E- %s : Unable to initialize DEM \n", __FILE__);
253 printf(
"Loading ice mask file from %s\n",
input->icefile);
255 (
int)
day,
input->ice_threshold) != 0) {
256 printf(
"-E- %s : Unable to initialize ice mask\n", __FILE__);
263 int32_t yr = (int32_t)
year;
264 int32_t dy = (int32_t)
day;
265 int32_t ms = (int32_t) (sec * 1.e3);
269 for (iw = 0; iw <
nbands; iw++) {
275 for (ix = 0; ix <
l1_input->xcal_nwave; ix++) {
278 printf(
"-E- %s line %d: xcal wavelength %f does not match sensor\n",
279 __FILE__, __LINE__,
l1_input->xcal_wave[ix]);
284 for (ip = 0; ip <
l1rec->npix; ip++) {
287 l1rec->Lt[ipb] = -999.0;
290 if (
l1rec->Lt[ipb] > 0.0 &&
l1rec->Lt[ipb] < 1000.0)
291 l1rec->Lt[ipb] /= rvs[ip];
296 for (ip = 0; ip <
l1rec->npix; ip++) {
299 for (iw = 0; iw <
nbands; iw++) {
302 if (
l1rec->Lt[ipb] > 0.0 &&
l1rec->Lt[ipb] < 1000.0) {
309 if (!
l1rec->navfail[ip]) {
312 if (
l1rec->lon[ip] < -180.)
313 l1rec->lon[ip] += 360.0;
315 else if (
l1rec->lon[ip] > 180.0)
316 l1rec->lon[ip] -= 360.0;
320 if (
input->proc_land) {
322 l1file->terrain_corrected) != 0) {
323 printf(
"-E- %s line %d: Error getting terrain height.\n",
328 l1rec->height[ip] = 0.0;
331 if (
input->proc_ocean != 2 &&
334 printf(
"-E- %s line %d: Error setting land and bathymetry masks.\n",
338 if (!
l1rec->land[ip] &&
348 for (iw = 0; iw <
nbands; iw++) {
350 l1rec->sw_n [ipb] = 1.334;
355 l1rec->sw_a_avg [ipb] = aw [iw];
356 l1rec->sw_bb_avg[ipb] = bbw[iw];
362 if (!
l1rec->land[ip]) {
367 for (iw = 0; iw <
nbands; iw++) {
373 l1rec->sw_bb[ipb] *= bbw_fac;
374 l1rec->sw_bb_avg[ipb] *= bbw_fac;
385 if (
l1rec->delphi[ip] < -180.)
386 l1rec->delphi[ip] += 360.0;
387 else if (
l1rec->delphi[ip] > 180.0)
388 l1rec->delphi[ip] -= 360.0;
391 l1rec->csolz[ip] = cos(
l1rec->solz[ip] / radeg);
392 l1rec->csenz[ip] = cos(
l1rec->senz[ip] / radeg);
395 temp = sqrt((1.0 -
l1rec->csenz[ip] *
l1rec->csenz[ip])*(1.0 -
l1rec->csolz[ip] *
l1rec->csolz[ip]))
396 * cos(
l1rec->delphi[ip] / radeg);
397 l1rec->scattang[ip] = acos(
MAX(-
l1rec->csenz[ip] *
l1rec->csolz[ip] + temp, -1.0)) * radeg;
406 if (navfail_cnt !=
l1rec->npix) {
411 if (
input->pixel_anc_file[0])
414 if (
input->windspeed > -999)
415 for (ip = 0; ip <
l1rec->npix; ip++)
418 for (ip = 0; ip <
l1rec->npix; ip++)
421 for (ip = 0; ip <
l1rec->npix; ip++)
424 for (ip = 0; ip <
l1rec->npix; ip++)
427 for (ip = 0; ip <
l1rec->npix; ip++)
430 for (ip = 0; ip <
l1rec->npix; ip++)
439 for (ip = 0; ip <
l1rec->npix; ip++) {
446 char name[] =
"ws_noise";
448 l1rec->ws[ip] *= (1 + noise_factor);
451 char name[] =
"wd_noise";
453 l1rec->wd[ip] *= (1 + noise_factor);
456 char name[] =
"mw_noise";
458 l1rec->mw[ip] *= (1 + noise_factor);
461 char name[] =
"zw_noise";
463 l1rec->zw[ip] *= (1 + noise_factor);
466 char name[] =
"rh_noise";
468 l1rec->rh[ip] *= (1 + noise_factor);
471 char name[] =
"pr_noise";
473 l1rec->pr[ip] *= (1 + noise_factor);
476 char name[] =
"wv_noise";
478 l1rec->wv[ip] *= (1 + noise_factor);
481 char name[] =
"oz_noise";
483 l1rec->oz[ip] *= (1 + noise_factor);
485 if (no2_tropo_noise >= 0) {
486 char name[] =
"no2_tropo_noise";
488 l1rec->no2_tropo[ip] *= (1 + noise_factor);
490 if (no2_strat_noise >= 0) {
491 char name[] =
"no2_strat_noise";
493 l1rec->no2_strat[ip] *= (1 + noise_factor);
497 for (iw = 0; iw <
nbands; iw++) {
499 snr_factor =
input->lt_noise_scale[iw];
504 l1rec->Lt[ipb] *= (1 + noise_factor);
505 if (
input->bias_frac[iw] > 0.0) {
507 if (firstpassperband == iw) {
509 printf(
"-------Bias settings-------\n");
510 printf(
"Band: %d - Bias frac: %.3f\n", iw,
input->bias_frac[iw]);
523 if ((
input->proc_ocean != 0) && !
l1rec->land[ip] && !
l1rec->navfail[ip]) {
534 for (iw = 0; iw <
nbands; iw++) {
553 for (ib = 0; ib <
nbands; ib++) {
555 l1rec->Lr [ipb] = 0.0;
556 l1rec->t_sol [ipb] = 1.0;
557 l1rec->t_sen [ipb] = 1.0;
558 l1rec->tg_sol[ipb] = 1.0;
559 l1rec->tg_sen[ipb] = 1.0;
560 l1rec->t_o2 [ipb] = 1.0;
561 l1rec->t_h2o [ipb] = 1.0;
562 l1rec->polcor [ipb] = 1.0;