OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
atmocor1.c
Go to the documentation of this file.
1 #include "l12_proto.h"
2 
3 /* ========================================================================== */
4 /* module atmocor1() - computes pre-aerosol atmospheric components */
5 /* */
6 /* Written By: B. A. Franz, SAIC, SeaWiFS Project, February 1998 */
7 /* Conversion to C, May 2006 */
8 /* ========================================================================== */
9 
10 
11 /* ------------------------------------------------------------------- */
12 /* correction factor to remove oxygen absorption from La(765) */
13 
14 /* ------------------------------------------------------------------- */
15 float oxygen_aer(float airmass) {
16  /* base case: m80_t50_strato visibility (550nm ,0-2km):25km */
17  static float a[] = {-1.0796, 9.0481e-2, -6.8452e-3};
18  return (1.0 + pow(10.0, a[0] + airmass * a[1] + airmass * airmass * a[2]));
19 }
20 
21 
22 /* ------------------------------------------------------------------- */
23 /* correction factor to replace oxygen absorption to Lr(765) */
24 
25 /* ------------------------------------------------------------------- */
26 float oxygen_ray(float airmass) {
27  /* base case is the 1976 Standard atmosphere without aerosols */
28  static float a[] = {-1.3491, 0.1155, -7.0218e-3};
29  return (1.0 / (1.0 + pow(10.0, a[0] + airmass * a[1] + airmass * airmass * a[2])));
30 }
31 
32 
33 /* ------------------------------------------------------------------- */
34 /* main function, loads various quanitities into l1 record for 1 pixel */
35 
36 /* ------------------------------------------------------------------- */
37 
38 void atmocor1(l1str *l1rec, int32_t ip) {
39  static float p0 = STDPR;
40 
41  int32_t sensorID = l1rec->l1file->sensorID;
42  int32_t nwave = l1rec->l1file->nbands;
43 
44  float solz = l1rec->solz[ip];
45  float senz = l1rec->senz[ip];
46  float raz = l1rec->delphi[ip];
47  float mu0 = l1rec->csolz[ip];
48  float mu = l1rec->csenz[ip];
49 
50  float ws = l1rec->ws[ip];
51  float pr = l1rec->pr[ip];
52  float wv = l1rec->wv[ip];
53 
54  float *Fo = l1rec->Fo;
55  float *Tau_r = l1rec->l1file->Tau_r;
56 
57  float zero = 0.0;
58  int32_t ib765 = -1;
59  float airmass;
60  float a_o2;
61  float glint_coef_q;
62  float glint_coef_u;
63  int32_t ib, ipb;
64  float scaleRayleigh;
65 
66  airmass = 1.0 / mu0 + 1.0 / mu;
67  ipb = ip*nwave;
68 
69  /* Initialize output values */
70  for (ib = 0; ib < nwave; ib++) {
71 
72  l1rec->Lr [ipb + ib] = 0.0;
73  l1rec->L_q [ipb + ib] = 0.0;
74  l1rec->L_u [ipb + ib] = 0.0;
75  l1rec->tLf [ipb + ib] = 0.0;
76  l1rec->tg_sol[ipb + ib] = 1.0;
77  l1rec->tg_sen[ipb + ib] = 1.0;
78  l1rec->t_h2o [ipb + ib] = 1.0;
79  l1rec->t_o2 [ipb + ib] = 1.0;
80  l1rec->t_sol [ipb + ib] = exp(-0.5 * pr / p0 * Tau_r[ib] / mu0);
81  l1rec->t_sen [ipb + ib] = exp(-0.5 * pr / p0 * Tau_r[ib] / mu);
82  l1rec->tg_sol[ipb + ib] = 1.0;
83  l1rec->tg_sen[ipb + ib] = 1.0;
84 
85  // Explicitly only doing the Ding and Gordon correction if the sensor has a band AT 765nm
86  // So, you know, SeaWiFS, OCTS, OSMI, and any others to be named later...
87  if (input->oxaband_opt == 1 && l1rec->l1file->iwave[ib] == 765) {
88  ib765 = ib;
89  l1rec->t_o2[ipb + ib765] = 1.0 / oxygen_aer(airmass);
90  }
91 
92  if (sensorID == SEAWIFS && ((input->gas_opt & GAS_TRANS_TBL_BIT) == 0)) {
93  /* this is for rhos only, but effects seawifs land products and cloud */
94  /* will modify get_rhos() to use gaseous transmittance in future update */
95  l1rec->t_h2o[ipb + ib] = water_vapor(ib, wv, airmass);
96  }
97 
98  }
99 
100  /* apply gaseous transmittance */
102 
103  /* white-cap radiances at TOA */
104  whitecaps(sensorID, l1_input->evalmask, nwave, ws, input->wsmax, &l1rec->rhof[ipb]);
105  for (ib = 0; ib < nwave; ib++) {
106  l1rec->tLf[ipb + ib] = l1rec->rhof[ipb + ib] * l1rec->t_sen[ipb + ib] * l1rec->t_sol[ipb + ib] * Fo[ib] * mu0 / M_PI;
107  }
108 
109  /* Rayleigh scattering */
110  if (sensorID != AVHRR && sensorID != OCRVC) {
111  rayleigh(l1rec, ip);
112  }
113 
114  // If we are running with Ding and Gordon, need to do the rayleigh part as well...
115  if (input->oxaband_opt == 1 && ib765 > -1) {
116  a_o2 = oxygen_ray(airmass);
117  l1rec->Lr [ipb + ib765] *= a_o2;
118  l1rec->L_q[ipb + ib765] *= a_o2;
119  l1rec->L_u[ipb + ib765] *= a_o2;
120  }
121 
122  //Scale by the altitude of the sensor, assuming height of atmosphere=100km
123  if (l1rec->alt > 0) {
124 
125  scaleRayleigh = 1.0 - exp(-l1rec->alt / 10); // Assume 10km is e-folding height
126 
127  for (ib = 0; ib < nwave; ib++) {
128  l1rec->Lr [ipb + ib] *= scaleRayleigh;
129  l1rec->L_q[ipb + ib] *= scaleRayleigh;
130  l1rec->L_u[ipb + ib] *= scaleRayleigh;
131  }
132  }
133 
134  /* glint coefficients and approximate glint radiances */
135  /* also add glint to polarization components */
136 
137  /* for avhrr, l1_aci_hdf.c calls avhrrsub5h.f which calls getglint */
138  if (sensorID != AVHRR) {
139 
140  getglint_iqu_(&senz, &solz, &raz, &ws, &zero,
141  &l1rec->glint_coef[ip], &glint_coef_q, &glint_coef_u);
142 
143  for (ib = 0; ib < nwave; ib++) {
144  l1rec->TLg[ipb + ib] = l1rec->glint_coef[ip] * exp(-(Tau_r[ib] + 0.1) * airmass) * Fo[ib];
145  l1rec->L_q[ipb + ib] += (glint_coef_q * l1rec->TLg[ipb + ib]);
146  l1rec->L_u[ipb + ib] += (glint_coef_u * l1rec->TLg[ipb + ib]);
147  }
148  }
149 
150 }
float oxygen_ray(float airmass)
Definition: atmocor1.c:26
#define AVHRR
Definition: sensorDefs.h:15
read l1rec
float mu
void rayleigh(l1str *l1rec, int32_t ip)
Definition: rayleigh.c:130
instr * input
float water_vapor
Definition: atrem_corl1.h:226
void atmocor1(l1str *l1rec, int32_t ip)
Definition: atmocor1.c:38
void gaseous_transmittance(l1str *l1rec, int32_t ip)
Definition: gas_trans.c:450
l1_input_t * l1_input
Definition: l1_options.c:9
#define M_PI
Definition: pml_iop.h:15
void whitecaps(int32_t sensorID, int32_t evalmask, int32_t nwave, float ws, float ws_max, float rhof[])
Definition: whitecaps.c:51
#define STDPR
Definition: l12_parms.h:85
int getglint_iqu_(float *, float *, float *, float *, float *, float *, float *, float *)
float oxygen_aer(float airmass)
Definition: atmocor1.c:15
#define GAS_TRANS_TBL_BIT
Definition: l12_parms.h:62
float mu0
#define OCRVC
Definition: sensorDefs.h:24
#define SEAWIFS
Definition: sensorDefs.h:12
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:97