Due to the lapse in federal government funding, NASA is not updating this website. We sincerely regret this inconvenience.
NASA Logo
Ocean Color Science Software

ocssw V2022
glint.c
Go to the documentation of this file.
1 #include "l12_proto.h"
2 
3 /* ============================================================================
4 
5 c This corrects the sunglint contamination reflectances in the
6 c SeaWiFS 8 bands using the Cox & Munk model for the ocean
7 c sun glitter radiance distribution as function of the sea surface
8 c wind.
9 c
10 c Inputs:
11 c num_iter, I, --- iteration number in the atmospheric corrections.
12 c nband, I, --- number of bands for the sensor (e.g., 8 for SeaWiFS).
13 c glint_coef, R, --- glitter radiance (F0=1) from Cox & Munk.
14 c air_mass, R, --- airmass value.
15 c mu0, R, --- cosine of the solar zenith angle.
16 c taur(nband), R, --- Rayleigh optical thicknesses.
17 c taua(nband), R, --- retrieved aerosol optical thicknesses.
18 c La(nband), R, --- aerosol reflectances at 8 SeaWiFS bands.
19 c Output:
20 c TLg(nband), R, --- sunglint radiances at 8 SeaWiFS bands.
21 c Credits:
22 c Written by
23 c Menghua Wang
24 c UMBC, Code 970.2, NASA/GSFC, Greenbelt, MD
25 c 10-7-1999
26 c
27 c Modification History
28 c - Modified to return glint radiance at TOA rather than to
29 c correct an input reflectance. Bryan Franz, 14 October 1999.
30 c - Added low rhoa enhancements from M. Wang, 28 November 1999.
31 c - Added a check and necessary correction to make sure there is
32 c no over-correction, i.e., there is no pixel lost due to sun
33 c glint corrections. Menghua Wang, 2-18-00
34 c ============================================================================= */
35 
36 static float taua_est(float x) {
37  return (-0.8 - 0.4 * log(x));
38 };
39 
40 void glint_rad(int32_t iter, int32_t nband, int32_t nir_s, int32_t nir_l,
41  float glint_coef, float airmass,
42  float mu0, float F0[], float taur[], float taua[], float La[], float TLg[], uncertainty_t *uncertainty) {
43  static float pi = PI;
44  static float glint_min = GLINT_MIN;
45  static float taua_min = 0.08;
46  static float taua_ave = 0.1;
47  static float rhoa_min = 0.01;
48  static float rhoa_min2 = 0.008;
49  static int32_t iter_max = 2;
50  static float rfac = 0.8;
51  float *derv_Lg_taua=NULL;
52  if(uncertainty)
53  derv_Lg_taua=uncertainty->derv_Lg_taua;
54 
55  int32_t ib;
56  float taua_c;
57  float refl_test;
58  float taua_ave2;
59  float fac;
60  int Iftaua=0;
61  float derv_taua_c;
62 
63 
64  /* If the number of iterations exceeds the maximum, we just return. This assumes */
65  /* that the calling routine saved the TLg from the previous iteration. If the glint */
66  /* coefficient is very low, return 0. */
67 
68  if (iter > iter_max)
69  return;
70 
71  else if (glint_coef <= glint_min)
72  for (ib = 0; ib < nband; ib++) {
73  TLg[ib] = 0.0;
74  if(uncertainty)
75  derv_Lg_taua[ib]=0.0;
76  } else {
77 
78  refl_test = pi / mu0 * (La[nir_l] / F0[nir_l] - glint_coef * exp(-(taur[nir_l] + taua_ave) * airmass));
79 
80  if (refl_test <= rhoa_min)
81  taua_ave2 = taua_est(10. * MAX(refl_test, 0.0001));
82  else
83  taua_ave2 = taua_ave;
84 
85  for (ib = nband - 1; ib >= 0; ib--) {
86 
87  if(uncertainty)
88  derv_Lg_taua[ib]=0.0;
89  if (iter <= 1) {
90  taua_c = taua_ave2;
91  derv_taua_c=0.0;
92  } else if (taua[nir_l] <= taua_min) {
93  taua_c = taua_est(taua[nir_l]);
94  Iftaua=1;
95 
96  if(uncertainty) {
97  //derv_taua_c=0;
98  //if(ib==nir_l)
99  derv_taua_c=-0.4/taua[nir_l];//*taua[nir_l]/taua[ib];
100  }
101  } else {
102  taua_c = taua[ib];
103  Iftaua=1;
104  derv_taua_c=taua[ib]/taua[nir_l];
105  }
106 
107  /* Check for over-correction */
108  if (ib == nir_l)
109  refl_test = pi / mu0 * (La[ib] / F0[ib] - glint_coef * exp(-(taur[ib] + taua_c) * airmass));
110 
111  if (refl_test <= rhoa_min2){
112  TLg[ib] = F0[ib] * glint_coef * exp(-(taur[ib] + 1.5 * taua_c) * airmass);
113  if(Iftaua && uncertainty)
114  derv_Lg_taua[ib]=-TLg[ib]*1.5*airmass*derv_taua_c; // TODO: fix the problem when taua_c equals to taua_est(taua[nir_l]);
115  } else {
116  TLg[ib] = F0[ib] * glint_coef * exp(-(taur[ib] + taua_c) * airmass);
117  if(Iftaua && uncertainty)
118  derv_Lg_taua[ib]=-TLg[ib]*airmass*derv_taua_c;
119  }
120  }
121 
122 
123  /* Make sure there is no over-correction */
124  if (La[nir_l] > 0.0 && La[nir_s] > 0.0) {
125  fac = MAX(TLg[nir_l] / La[nir_l], TLg[nir_s] / La[nir_s]);
126  if (fac >= rfac) {
127  for (ib = 0; ib < nband; ib++) {
128  TLg[ib] = rfac * TLg[ib] / fac;
129  if(uncertainty)
130  derv_Lg_taua[ib]*=(rfac/fac);
131  }
132 
133  }
134 
135  }
136 
137  }
138 }
139 
140 
141 
142 
143 
144 
#define MAX(A, B)
Definition: swl0_utils.h:25
#define NULL
Definition: decode_rs.h:63
map< string, float > F0
Definition: DDSensor.cpp:39
const double pi
void glint_rad(int32_t iter, int32_t nband, int32_t nir_s, int32_t nir_l, float glint_coef, float airmass, float mu0, float F0[], float taur[], float taua[], float La[], float TLg[], uncertainty_t *uncertainty)
Definition: glint.c:40
#define fac
#define PI
Definition: l3_get_org.c:6
#define GLINT_MIN
Definition: l1.h:60
int32_t nband
float mu0