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