ocssw V2020
las_iop.c
Go to the documentation of this file.
1 /* --------------------------------------------------------------------------------------- */
2 /* Loisel & Stramski IOP model */
3 /* */
4 /* References: */
5 /* */
6 /* H. Loisel, J.M. Nicolas, A. Sciandra, D. Stramski, and A. Poteau. 2006. The */
7 /* spectral dependency of optical backscattering by marine particles from satellite */
8 /* remote sensing of the global ocean. Journal of Geophysical Research, 111, C09024, */
9 /* doi: 10.1029/2005JC003367. */
10 /* */
11 /* H. Loisel, D. Stramski, B. G. Mitchell, F. Fell, V. Fournier-Sicre, B. Lemasle */
12 /* and M. Babin. 2001. Comparison of the ocean inherent optical properties obtained */
13 /* from measurements and inverse modeling. Applied Optics.40: 2384-2397. */
14 /* */
15 /* H. Loisel, E. Bosc D. Stramski, K. Oubelker and P-Y. Deschamps. 2001. Seasonal */
16 /* variability of the backscattering coefficients in the Mediterranean Sea based */
17 /* on Satellite SeaWIFS imagery. Geophysical Research letters. 28: 4203-4206. */
18 /* */
19 /* H. Loisel, J.M. Nicolas, P.Y.Deschamps, and R. Frouin. 2002. Seasonal and */
20 /* inter-annual variability of the particulate matter in the global ocean. */
21 /* Geophysical Research letters 29: 2996. */
22 /* */
23 /* H. Loisel and D. Stramski. 2000. Estimation of the inherent optical properties */
24 /* of natural waters from irradiance attenuation coefficient and reflectance in */
25 /* the presence of Raman scattering. Applied Optics. 39: 3001-3011. */
26 /* */
27 /* Fortran code provided by H. Loisel, May 2008. */
28 /* */
29 /* Implementation: */
30 /* */
31 /* B. Franz, NASA/OBPG, June 2008. */
32 /* --------------------------------------------------------------------------------------- */
33 
34 #include <stdlib.h>
35 #include <math.h>
36 #include "l12_proto.h"
37 #include "l2prod.h"
38 #include "amoeba.h"
39 
40 #define LASNSOL 3
41 #define LASNKC 3
42 #define LASNRC 2
43 
44 typedef float r_array[LASNSOL][LASNRC];
45 typedef float k_array[LASNSOL][LASNKC];
46 
47 typedef struct las_table_struc {
48  int nwav;
49  int nsol;
50  int nrc;
51  int nkc;
52  float *wav;
53  float sol[LASNSOL];
56 } lastabstr;
57 
58 static lastabstr tab; // R(0-) and <Kd>1 coefficient table
59 
60 static int LastRecNum = -1;
61 static float badData = BAD_FLT;
62 
63 static int nwave = -1; // number of wavelengths to fit
64 static float *wave; // sensor wavelengths to fit
65 static float *a; // total absorption coefficient per band and pixel
66 static float *b; // total scattering coefficient per band and pixel
67 static float *c; // beam attenuation coefficient per band and pixel
68 static float *bb; // backscatter coefficient per band and pixel
69 static float *bbp; // particulate backscatter coefficient per band and pixel
70 static float *aw; // pure-water total absorption per band
71 static float *bbw; // pure-water backscattering per band
72 
73 
74 
75 /* ------------------------------------------------------------------------------- */
76 /* read_las_tables() - load Loisel & Stramski R0 and Kd coefficient tables */
77 
78 /* ------------------------------------------------------------------------------- */
80  FILE *fp;
81  char *tmp_str;
82  char fname[FILENAME_MAX];
83  char sensor_name[FILENAME_MAX];
84  int iwav, isol;
85 
86 
87  tab.nsol = LASNSOL;
88  tab.nkc = LASNKC;
89  tab.nrc = LASNRC;
90 
91  if ((tmp_str = getenv("OCDATAROOT")) == NULL) {
92  printf("OCDATAROOT environment variable is not defined.\n");
93  exit(1);
94  }
95 
96  /* sensor specific LUTs used - only available SeaWiFS */
97  switch (sensorID) {
98  case SEAWIFS:
99  sprintf(sensor_name, "seawifs");
100  tab.nwav = 5;
101  break;
102  default: /* interpolate from seawifs wavelengths */
103  sprintf(sensor_name, "seawifs");
104  tab.nwav = 5;
105  break;
106  }
107 
108  if (tab.rc == NULL) {
109  if ((tab.rc = (r_array *) calloc(tab.nwav, sizeof (r_array))) == NULL) {
110  printf("-E- : Error allocating memory to read_las_tables\n");
111  exit(FATAL_ERROR);
112  }
113  if ((tab.kc = (k_array *) calloc(tab.nwav, sizeof (k_array))) == NULL) {
114  printf("-E- : Error allocating memory to read_las_tables\n");
115  exit(FATAL_ERROR);
116  }
117  if ((tab.wav = (float *) calloc(tab.nwav, sizeof (float))) == NULL) {
118  printf("-E- : Error allocating memory to read_las_tables\n");
119  exit(FATAL_ERROR);
120  }
121  }
122  printf("Loading Loisel & Stramski IOP model tables:\n");
123 
124  sprintf(fname, "%s/%s/iop/las/%s", tmp_str, sensor_name, "LUT_RRS");
125  printf(" %s\n", fname);
126  if ((fp = fopen(fname, "r")) == NULL) {
127  printf("Error opening %s\n", fname);
128  exit(1);
129  }
130  for (isol = 0; isol < tab.nsol; isol++) for (iwav = 0; iwav < tab.nwav; iwav++)
131  fscanf(fp, "%f %f %f %f", &tab.wav[iwav], &tab.sol[isol], &tab.rc[iwav][isol][0], &tab.rc[iwav][isol][1]);
132  fclose(fp);
133 
134  sprintf(fname, "%s/%s/iop/las/%s", tmp_str, sensor_name, "LUT_KD");
135  printf(" %s\n", fname);
136  if ((fp = fopen(fname, "r")) == NULL) {
137  printf("Error opening %s\n", fname);
138  exit(1);
139  }
140  for (isol = 0; isol < tab.nsol; isol++) for (iwav = 0; iwav < tab.nwav; iwav++)
141  fscanf(fp, "%f %f %f %f %f", &tab.wav[iwav],
142  &tab.sol[isol], &tab.kc[iwav][isol][0], &tab.kc[iwav][isol][1], &tab.kc[iwav][isol][2]);
143  fclose(fp);
144 }
145 
146 
147 /* ------------------------------------------------------------------------------- */
148 /* computes R(0-) and <Kd>1 at one wavelength from Rrs and Rrs(443)/Rrs(555) */
149 
150 /* ------------------------------------------------------------------------------- */
151 void get_R0_Kd(float rat, float Rrs, float wave, float solz, float *R0, float *Kd) {
152  float log_q = log10(rat);
153  int iwav = windex(wave, tab.wav, tab.nwav);
154  float dwav = wave - tab.wav[iwav];
155 
156  float R01, R02;
157  float Kd1, Kd2;
158 
159  if (fabs(dwav) > 1.0) {
160 
161  // if the input wavelength is not one of the table wavelengths, call the
162  // function recursively for bounding table wavelengths and interpolate
163 
164  int iwav1, iwav2;
165  if (dwav > 0.0) {
166  iwav2 = MIN(iwav + 1, tab.nwav - 1);
167  iwav1 = iwav2 - 1;
168  } else {
169  iwav1 = MAX(iwav - 1, 0);
170  iwav2 = iwav1 + 1;
171  }
172  get_R0_Kd(rat, Rrs, tab.wav[iwav1], solz, &R01, &Kd1);
173  get_R0_Kd(rat, Rrs, tab.wav[iwav2], solz, &R02, &Kd2);
174  *R0 = R01 + (wave - tab.wav[iwav1]) / (tab.wav[iwav2] - tab.wav[iwav1])*(R02 - R01);
175  *Kd = Kd1 + (wave - tab.wav[iwav1]) / (tab.wav[iwav2] - tab.wav[iwav1])*(Kd2 - Kd1);
176 
177  } else {
178 
179  // compute R(0-) and <Kd>1 for bounding solar zenith angles of the
180  // coefficient table and interpolate to input solar zenith angle
181 
182  int isol1, isol2;
183  float solz1, solz2;
184 
185  isol2 = 0;
186  while (tab.sol[isol2] < solz) isol2++;
187  isol2 = MAX(MIN(isol2, tab.nsol - 1), 1);
188  isol1 = isol2 - 1;
189 
190  solz1 = tab.sol[isol1];
191  solz2 = tab.sol[isol2];
192 
193  R01 = tab.rc[iwav][isol1][0] * pow(Rrs, tab.rc[iwav][isol1][1]);
194  R02 = tab.rc[iwav][isol2][0] * pow(Rrs, tab.rc[iwav][isol2][1]);
195 
196  Kd1 = pow(10.0, (tab.kc[iwav][isol1][0] * log_q + tab.kc[iwav][isol1][1]) / (tab.kc[iwav][isol1][2] + log_q));
197  Kd2 = pow(10.0, (tab.kc[iwav][isol2][0] * log_q + tab.kc[iwav][isol2][1]) / (tab.kc[iwav][isol2][2] + log_q));
198 
199  *R0 = R01 + (solz - solz1)*(R02 - R01) / (solz2 - solz1);
200  *Kd = Kd1 + (solz - solz1)*(Kd2 - Kd1) / (solz2 - solz1);
201  }
202 
203 }
204 
205 
206 /* ------------------------------------------------------------------------------- */
207 /* have we run for this scan line? */
208 
209 /* ------------------------------------------------------------------------------- */
210 int las_ran(int recnum) {
211  if (recnum == LastRecNum)
212  return 1;
213  else
214  return 0;
215 }
216 
217 
218 /* ------------------------------------------------------------------------------- */
219 /* allocates private arrays */
220 
221 /* ------------------------------------------------------------------------------- */
222 void alloc_las(int npix, int nbands) {
223  a = (float*) calloc(nbands, sizeof (float));
224  b = (float*) calloc(nbands, sizeof (float));
225  c = (float*) calloc(nbands, sizeof (float));
226  bb = (float*) calloc(nbands, sizeof (float));
227  bbp = (float*) calloc(nbands, sizeof (float));
228  aw = (float*) calloc(nbands, sizeof (float));
229  bbw = (float*) calloc(nbands, sizeof (float));
230 }
231 
232 
233 /* ------------------------------------------------------------------------------- */
234 /* computes eta = bw/b */
235 
236 /* ------------------------------------------------------------------------------- */
237 float eta_func(float bbw, float bb) {
238  float bw = bbw * 2.0;
239  float bbp, b;
240 
241  if (bb <= bbw)
242  bbp = bbw / 10.0;
243  else
244  bbp = bb - bbw;
245 
246  b = bw + bbp / 0.0183;
247 
248  return (bw / b);
249 }
250 
251 
252 /* ------------------------------------------------------------------------------- */
253 /* computes alpha exponent of bb function */
254 
255 /* ------------------------------------------------------------------------------- */
256 float alpha_func(float solz, float eta) {
257  float a = -0.0007 * solz + 0.1024;
258  float b = -0.0042 * solz + 0.3594;
259  return (a * log10(eta) + b);
260 }
261 
262 
263 /* ------------------------------------------------------------------------------- */
264 /* computes delta exponent of bb function */
265 
266 /* ------------------------------------------------------------------------------- */
267 float delta_func(float eta) {
268  return (0.871 + 0.40 * eta - 1.83 * pow(eta, 2.0));
269 }
270 
271 
272 /* ------------------------------------------------------------------------------- */
273 /* run the model, collect the output */
274 
275 /* ------------------------------------------------------------------------------- */
276 void run_las(l2str *l2rec, int ip) {
277  static int firstCall = 1;
278  static int ib443 = -1;
279  static int ib555 = -1;
280  static int maxiter = 4;
281  static float nw = 1.334;
282  float *Rrs, ratio;
283  float R0, Kd;
284  float solz, mu;
285  float alpha, delta, eta;
286  float h, m, minh, maxh, ec50;
287  int status;
288  int ib, it;
289 
290  l1str *l1rec = l2rec->l1rec;
291  int32_t nbands = l1rec->l1file->nbands;
292 
293  // Even though these are static arrays they have to be re-allocated each
294  // call because bin files have varying npix over scan lines
295  //
296  if (firstCall) {
297 
298  firstCall = 0;
299 
300  alloc_las(l1rec->npix, nbands);
301 
302  wave = l1rec->l1file->fwave;
303  ib443 = windex(443, wave, nbands);
304  ib555 = windex(555, wave, nbands);
305  nwave = ib555 + 1;
306 
307  read_las_tables(l1rec->l1file->sensorID);
308  get_aw_bbw(l2rec, wave, nwave, aw, bbw);
309  }
310 
311  if ((Rrs = (float *) calloc(nwave, sizeof (float))) == NULL) {
312  printf("-E- : Error allocating memory to run_las\n");
313  exit(FATAL_ERROR);
314  }
315 
316  status = 0;
317 
318  // check for negative radiances
319 
320  for (ib = 0; ib < nwave; ib++) {
321  Rrs[ib] = l2rec->Rrs[ip * nbands + ib];
322  if (Rrs[ib] <= 0.0) status = 1;
323  }
324 
325  // if no negatives and pixel not already masked, run model
326 
327  if (status == 0 && !l1rec->mask[ip]) {
328 
329  if ((input->brdf_opt & FOQMOREL) != 0)
330  solz = 0.0;
331  else
332  solz = MIN(l1rec->solz[ip], 60.0);
333  ratio = Rrs[ib443] / Rrs[ib555];
334  mu = cos(asin(sin(solz / RADEG) / nw));
335 
336  for (ib = 0; ib < nwave; ib++) {
337 
338  get_R0_Kd(ratio, Rrs[ib], wave[ib], solz, &R0, &Kd);
339 
340  eta = 0.05;
341  for (it = 0; it < maxiter; it++) {
342  alpha = alpha_func(solz, eta);
343  delta = delta_func(eta);
344  bb[ib] = Kd * pow(10, alpha) * pow(R0, delta);
345  eta = eta_func(bbw[ib], bb[ib]);
346  }
347 
348  minh = -0.0034 * solz + 1.248;
349  maxh = -0.0084 * solz + 1.7223;
350  ec50 = 0.0033 * solz - 1.9837;
351 
352  m = 0.0034 * pow(solz, 2) - 0.0674 * solz - 9.34;
353  h = pow(10.0, minh + (maxh - minh) / (1 + pow(10, (ec50 - log10(eta)) * m)));
354 
355  a[ib] = mu * Kd / sqrt(1 + h * R0 / (1 - R0));
356  b[ib] = bbw[ib]*2.0 / eta;
357  c[ib] = a[ib] + b[ib];
358  bbp[ib] = bb[ib] - bbw[ib];
359 
360  if (!isfinite(a[ib]) || !isfinite(bb[ib])) {
361  a [ib] = badData;
362  b [ib] = badData;
363  c [ib] = badData;
364  bb [ib] = badData;
365  bbp[ib] = badData;
366  }
367  }
368 
369  } else {
370 
371  for (ib = 0; ib < nwave; ib++) {
372  a [ib] = badData;
373  b [ib] = badData;
374  c [ib] = badData;
375  bb [ib] = badData;
376  bbp[ib] = badData;
377  }
378  }
379 
380 
381  LastRecNum = l1rec->iscan;
382  free(Rrs);
383  return;
384 }
385 
386 
387 /* ------------------------------------------------------------------- */
388 /* */
389 
390 /* ------------------------------------------------------------------- */
391 double las_eta_amb(FITSTRUCT *ambdata, double par[]) {
392  int iw;
393 
394  ambdata->merit = 0.0;
395  for (iw = 0; iw < nwave; iw++) {
396  ambdata->yfit[iw] = par[0] * pow(wave[0] / wave[iw], par[1]);
397  ambdata->merit += pow((ambdata->y[iw] - ambdata->yfit[iw]), 2) * ambdata->wgt[iw];
398  }
399 
400  return (ambdata->merit);
401 }
402 
403 
404 /* ------------------------------------------------------------------- */
405 /* */
406 /* ------------------------------------------------------------------- */
407 #define NPARETALAS 2
408 
409 float fit_las_eta_amb(float *bbp) {
410  static int firstCall = 1;
411  static float tol = 1.e-6; /* fractional change in chisqr */
412  static FITSTRUCT ambdata; /* amoeba interface structure */
413  static double init[NPARETALAS * (NPARETALAS + 1)]; /* initial simplex */
414  static double par [NPARETALAS];
415  static double len [NPARETALAS];
416  static double *wts;
417  static double *y;
418  static double *yfit;
419  static int npar = NPARETALAS;
420  static int maxiter = 100;
421 
422  int i, j;
423  short isml;
424 
425  if (firstCall) {
426  firstCall = 0;
427  if ((wts = (double *) calloc(nwave, sizeof (double))) == NULL) {
428  printf("-E- : Error allocating memory to fit_las_eta_amb\n");
429  exit(FATAL_ERROR);
430  }
431  if ((y = (double *) calloc(nwave, sizeof (double))) == NULL) {
432  printf("-E- : Error allocating memory to fit_las_eta_amb\n");
433  exit(FATAL_ERROR);
434  }
435  if ((yfit = (double *) calloc(nwave, sizeof (double))) == NULL) {
436  printf("-E- : Error allocating memory to fit_las_eta_amb\n");
437  exit(FATAL_ERROR);
438  }
439  for (i = 0; i < nwave; i++) {
440  wts[i] = 1.0;
441  }
442  ambdata.nfunc = npar; /* number of model parameters */
443  ambdata.npnts = nwave; /* number of wavelengths */
444  ambdata.wgt = wts; /* Input weights on values */
445  ambdata.meta = NULL;
446  // ambdata.niter = 1;
447  }
448 
449  for (i = 0; i < nwave; i++) {
450  y[i] = (double) bbp[i];
451  }
452 
453  ambdata.y = y; /* Input values */
454  ambdata.yfit = yfit; /* Output model predicted values */
455 
456  par[0] = y[0];
457  len[0] = 0.01;
458  par[1] = 0.0;
459  len[1] = 2.0;
460 
461  /* initialize simplex with first guess model parameters */
462  for (j = 0; j < npar + 1; j++)
463  for (i = 0; i < npar; i++)
464  init[j * npar + i] = par[i];
465 
466  for (i = 0; i < npar; i++) {
467  init[npar + i * (npar + 1)] += len[i];
468  par[i] = 0.0;
469  }
470 
471  /* run optimization */
472  isml = amoeba(init, &ambdata, las_eta_amb, tol);
473 
474  for (i = 0; i < npar; i++) {
475  par[i] = init[npar * isml + i];
476  }
477 
478  /* check convergence and record parameter results */
479  if (ambdata.niter >= maxiter || par[0] == BAD_FLT || !isfinite(par[1]))
480  return (BAD_FLT);
481  else
482  return (par[1]);
483 }
484 
485 
486 
487 
488 /* ------------------------------------------------------------------------------- */
489 /* interface to l2_hdf_generic() */
490 
491 /* ------------------------------------------------------------------------------- */
492 void get_las(l2str *l2rec, l2prodstr *p, float prod[]) {
493  int prodID = p->cat_ix;
494  int ib = p->prod_ix;
495  int ip;
496 
497  l1str *l1rec = l2rec->l1rec;
498 
499  for (ip = 0; ip < l1rec->npix; ip++) {
500 
501  run_las(l2rec, ip);
502 
503  if (ib >= nwave) {
504  prod[ip] = p->badData;
505  l1rec->flags[ip] |= PRODFAIL;
506  continue;
507  }
508 
509 
510  switch (prodID) {
511 
512  case CAT_a_las:
513  if (a[ib] > badData)
514  prod[ip] = a[ib];
515  else {
516  prod[ip] = p->badData;
517  l1rec->flags[ip] |= PRODFAIL;
518  }
519  break;
520 
521  case CAT_b_las:
522  if (b[ib] > badData)
523  prod[ip] = b[ib];
524  else {
525  prod[ip] = p->badData;
526  l1rec->flags[ip] |= PRODFAIL;
527  }
528  break;
529 
530  case CAT_c_las:
531  if (c[ib] > badData)
532  prod[ip] = c[ib];
533  else {
534  prod[ip] = p->badData;
535  l1rec->flags[ip] |= PRODFAIL;
536  }
537  break;
538 
539  case CAT_bb_las:
540  if (bb[ib] > badData)
541  prod[ip] = bb[ib];
542  else {
543  prod[ip] = p->badData;
544  l1rec->flags[ip] |= PRODFAIL;
545  }
546  break;
547 
548  case CAT_bbp_las:
549  if (bbp[ib] > badData)
550  prod[ip] = bbp[ib];
551  else {
552  prod[ip] = p->badData;
553  l1rec->flags[ip] |= PRODFAIL;
554  }
555  break;
556 
557  case CAT_bbps_las:
558  prod[ip] = get_bbp_las_eta(l2rec, ip);
559  if (prod[ip] == BAD_FLT) {
560  prod[ip] = p->badData;
561  l1rec->flags[ip] |= PRODFAIL;
562  }
563  break;
564 
565  default:
566  printf("-E- %s line %d : erroneous product ID %d passed to Loisel & Stramski model().\n",
567  __FILE__, __LINE__, prodID);
568  exit(1);
569  }
570  }
571 
572  return;
573 }
574 
575 
576 
577 /* ------------------------------------------------------------------------------- */
578 /* interface to convl12() to return iops */
579 
580 /* ------------------------------------------------------------------------------- */
581 void iops_las(l2str *l2rec) {
582  int ib, ip;
583  int nbands = l2rec->l1rec->l1file->nbands;
584 
585  for (ip = 0; ip < l2rec->l1rec->npix; ip++) {
586  run_las(l2rec, ip);
587  for (ib = 0; ib < nwave; ib++) {
588  l2rec->a [ip * nbands + ib] = a [ib];
589  l2rec->bb[ip * nbands + ib] = bb[ib];
590  }
591  for (ib = nwave; ib < l2rec->l1rec->l1file->nbands; ib++) {
592  l2rec->a [ip * nbands + ib] = badData;
593  l2rec->bb[ip * nbands + ib] = badData;
594  }
595  }
596 
597  return;
598 }
599 
600 
601 /* ------------------------------------------------------------------------------- */
602 /* interface to giop() */
603 
604 /* ------------------------------------------------------------------------------- */
605 int get_bbp_las(l2str *l2rec, int ip, float tab_wave[], float tab_bbp[], int tab_nwave) {
606  int iw;
607 
608  run_las(l2rec, ip);
609 
610  for (iw = 0; iw < nwave; iw++) {
611  if (bbp[iw] < 0)
612  return (0);
613  }
614 
615  for (iw = 0; iw < tab_nwave; iw++) {
616  tab_bbp[iw] = linterp(wave, &bbp[0], nwave, tab_wave[iw]);
617  }
618 
619  return (1);
620 }
621 
622 
623 /* ------------------------------------------------------------------------------- */
624 /* interface to giop() */
625 
626 /* ------------------------------------------------------------------------------- */
627 float get_bbp_las_eta(l2str *l2rec, int ip) {
628  int iw;
629 
630  run_las(l2rec, ip);
631 
632  for (iw = 0; iw < nwave; iw++) {
633  if (bbp[iw] < 0)
634  return (BAD_FLT);
635  }
636 
637  return (fit_las_eta_amb(&bbp[0]));
638 }
639 
640 
float * wav
Definition: las_iop.c:52
#define MAX(A, B)
Definition: swl0_utils.h:26
#define MIN(x, y)
Definition: rice.h:169
void alloc_las(int npix, int nbands)
Definition: las_iop.c:222
int j
Definition: decode_rs.h:73
int status
Definition: l1_czcs_hdf.c:31
float m
Definition: mie_kernal.py:30
constexpr double RADEG
void iops_las(l2str *l2rec)
Definition: las_iop.c:581
#define CAT_b_las
Definition: l2prod.h:190
#define CAT_a_las
Definition: l2prod.h:189
int niter
Definition: amoeba.h:9
#define FOQMOREL
Definition: l12_parms.h:89
string fname
Definition: mie_kernal.py:124
void run_las(l2str *l2rec, int ip)
Definition: las_iop.c:276
#define NULL
Definition: decode_rs.h:63
#define NPARETALAS
Definition: las_iop.c:407
read l1rec
void read_las_tables(int sensorID)
Definition: las_iop.c:79
float mu
float r_array[LASNSOL][LASNRC]
Definition: las_iop.c:44
float h[MODELMAX]
Definition: atrem_corl1.h:131
#define PRODFAIL
Definition: l2_flags.h:39
#define CAT_bbp_las
Definition: l2prod.h:193
short amoeba(double *pnts, FITSTRUCT *auxdata, double(*func)(FITSTRUCT *, double[]), float tol)
Definition: amoeba.c:14
double merit
Definition: amoeba.h:4
instr * input
float delta_func(float eta)
Definition: las_iop.c:267
#define BAD_FLT
Definition: jplaeriallib.h:19
int init(int32_t ipr, int32_t jpr, char *efile, char *pfile)
Definition: proj_report.c:51
k_array * kc
Definition: las_iop.c:55
float get_bbp_las_eta(l2str *l2rec, int ip)
Definition: las_iop.c:627
int get_bbp_las(l2str *l2rec, int ip, float tab_wave[], float tab_bbp[], int tab_nwave)
Definition: las_iop.c:605
read recnum
float alpha_func(float solz, float eta)
Definition: las_iop.c:256
float linterp(float xin[], float yin[], int32_t nin, float xout)
Definition: lspline.c:59
float eta_func(float bbw, float bb)
Definition: las_iop.c:237
double * wgt
Definition: amoeba.h:6
r_array * rc
Definition: las_iop.c:54
double alpha
#define FATAL_ERROR
Definition: swl0_parms.h:5
float tol
const double delta
#define LASNKC
Definition: las_iop.c:41
float sol[LASNSOL]
Definition: las_iop.c:53
void get_aw_bbw(l2str *l2rec, float wave[], int nwave, float *aw, float *bbw)
double * y
Definition: amoeba.h:5
double las_eta_amb(FITSTRUCT *ambdata, double par[])
Definition: las_iop.c:391
float k_array[LASNSOL][LASNKC]
Definition: las_iop.c:45
data_t b[NROOTS+1]
Definition: decode_rs.h:77
short int nfunc
Definition: amoeba.h:2
float fit_las_eta_amb(float *bbp)
Definition: las_iop.c:409
double * yfit
Definition: amoeba.h:8
int32_t nbands
#define fabs(a)
Definition: misc.h:93
void * meta
Definition: amoeba.h:10
#define CAT_bbps_las
Definition: l2prod.h:219
short int npnts
Definition: amoeba.h:3
#define LASNRC
Definition: las_iop.c:42
void get_las(l2str *l2rec, l2prodstr *p, float prod[])
Definition: las_iop.c:492
int las_ran(int recnum)
Definition: las_iop.c:210
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude resolving resolving GSFcd00179 Corrected handling of fill values for[Sensor|Solar][Zenith|Azimuth] resolving MODxl01751 Changed to validate LUT version against a value retrieved from the resolving MODxl02056 Changed to calculate Solar Diffuser angles without adjustment for estimated post launch changes in the MODIS orientation relative to incidentally resolving defects MODxl01766 Also resolves MODxl01947 Changed to ignore fill values in SCI_ABNORM and SCI_STATE rather than treating them as resolving MODxl01780 Changed to use spacecraft ancillary data to recognise when the mirror encoder data is being set by side A or side B and to change calculations accordingly This removes the need for seperate LUTs for Side A and Side B data it makes the new LUTs incompatible with older versions of the and vice versa Also resolves MODxl01685 A more robust GRing algorithm is being which will create a non default GRing anytime there s even a single geolocated pixel in a granule Removed obsolete messages from seed as required for compatibility with version of the SDP toolkit Corrected test output file names to end in per delivery and then split off a new MYD_PR03 pcf file for Aqua Added AssociatedPlatformInstrumentSensor to the inventory metadata in MOD01 mcf and MOD03 mcf Created new versions named MYD01 mcf and MYD03 where AssociatedPlatformShortName is rather than Terra The program itself has been changed to read the Satellite Instrument validate it against the input L1A and LUT and to use it determine the correct files to retrieve the ephemeris and attitude data from Changed to produce a LocalGranuleID starting with MYD03 if run on Aqua data Added the Scan Type file attribute to the Geolocation copied from the L1A and attitude_angels to radians rather than degrees The accumulation of Cumulated gflags was moved from GEO_validate_earth_location c to GEO_locate_one_scan c
Definition: HISTORY.txt:464
void get_R0_Kd(float rat, float Rrs, float wave, float solz, float *R0, float *Kd)
Definition: las_iop.c:151
#define CAT_bb_las
Definition: l2prod.h:192
#define SEAWIFS
Definition: sensorDefs.h:12
int i
Definition: decode_rs.h:71
PGE01 indicating that PGE02 PGE01 V6 for and PGE01 V2 for MOD03 were used to produce the granule By convention adopted in all MODIS Terra PGE02 code versions are The fourth digit of the PGE02 version denotes the LUT version used to produce the granule The source of the metadata environment variable ProcessingCenter was changed from a QA LUT value to the Process Configuration A sign used in error in the second order term was changed to a
Definition: HISTORY.txt:424
int32_t sensorID[MAXNFILES]
Definition: l2bin.cpp:95
int windex(float wave, float twave[], int ntwave)
Definition: windex.c:71
#define CAT_c_las
Definition: l2prod.h:191
#define LASNSOL
Definition: las_iop.c:40
Every product should define the units l2prod badData
float p[MODELMAX]
Definition: atrem_corl1.h:131