NASA Logo
Ocean Color Science Software

ocssw V2022
atmocor1_land.c
Go to the documentation of this file.
1 /* ================================================================ */
2 /* atmocor1_land - computes atmospheric components over land. */
3 /* */
4 /* Written By: B. A. Franz, SAIC GSC, NASA/SIMBIOS, April 2000 */
5 /* Based on code provided by Jacques Descloitres */
6 /* */
7 /* Revised by: M.Zhang, December 2023 */
8 /* add in a trace gas absorption correction for all species corrected */
9 /* for over ocean. */
10 /* */
11 /* ================================================================ */
12 
13 #include <math.h>
14 #include "l12_proto.h"
15 
16 
17 void chand(float xphi, float xmuv, float xmus, float *xtau,
18  float *rhoray, double *trup, double *trdown, int nbands);
19 
20 int atmocor1_land(l1str *l1rec, int32_t ip) {
21  static float pi = 3.141592654;
22  static float radeg = 180. / 3.141592654;
23  static float p0 = 1013.25;
24 
25  float delphi = l1rec->delphi[ip] + 180.0;
26  float mu0 = cos(l1rec->solz[ip] / radeg);
27  float mu = cos(l1rec->senz[ip] / radeg);
28  float airmass = 1.0 / mu0 + 1.0 / mu;
29  int nbands = l1rec->l1file->nbands;
30 
31  float *Taur;
32  float *rhor;
33  double *trup;
34  double *trdown;
35 
36  int32_t ib, ipb;
37 
38  if ((Taur = (float *) calloc(nbands, sizeof (float))) == NULL) {
39  printf("-E- : Error allocating memory to Taur\n");
40  exit(FATAL_ERROR);
41  }
42  if ((rhor = (float *) calloc(nbands, sizeof (float))) == NULL) {
43  printf("-E- : Error allocating memory to rhor\n");
44  exit(FATAL_ERROR);
45  }
46  if ((trup = (double *) calloc(nbands, sizeof (double))) == NULL) {
47  printf("-E- : Error allocating memory to trup\n");
48  exit(FATAL_ERROR);
49  }
50  if ((trdown = (double *) calloc(nbands, sizeof (double))) == NULL) {
51  printf("-E- : Error allocating memory to trdown\n");
52  exit(FATAL_ERROR);
53  }
54 
55  ipb = ip*nbands;
56  for (ib = 0; ib < nbands; ib++) {
57  l1rec->tg_sol[ipb + ib] = 1.0;
58  l1rec->tg_sen[ipb + ib] = 1.0;
59  l1rec->t_h2o [ipb + ib] = 1.0;
60  l1rec->t_o2 [ipb + ib] = 1.0;
61  }
62 
63  /* */
64  /* First, correct Rayleigh optical thickness for pressure. */
65  /* */
66  for (ib = 0; ib < nbands; ib++) {
67  Taur[ib] = l1rec->l1file->Tau_r[ib] * l1rec->pr[ip] / p0;
68  }
69 
70  /* */
71  /* Compute Rayleigh path reflectances, also total diff. trans. */
72  /* */
73  chand(delphi, mu, mu0, Taur, rhor, trup, trdown, nbands);
74 
75  /* Compute gaseous transmittance functions */
77 
78  /* */
79  /* Loop through bands and compute transmittance and reflectance */
80  /* */
81  for (ib = 0; ib < l1rec->l1file->nbands; ib++) {
82 
83  ipb = ip * l1rec->l1file->nbands + ib;
84 
85  /* Compute and store Rayleigh radiance and diff trans */
86  l1rec->Lr[ipb] = rhor[ib] * l1rec->Fo[ib] * mu0 / pi;
87  l1rec->t_sol[ipb] =
88  ((2.0 / 3.0 + mu0) + (2.0 / 3.0 - mu0) * trdown[ib])
89  / (4.0 / 3.0 + Taur[ib]);
90  l1rec->t_sen[ipb] =
91  ((2.0 / 3.0 + mu) + (2.0 / 3.0 - mu) * trup [ib])
92  / (4.0 / 3.0 + Taur[ib]);
93 
94  /* no way to comput polarization correction over land */
95  l1rec->polcor[ipb] = 1.0;
96 
97  if (l1rec->l1file->sensorID == SEAWIFS && ((input->gas_opt & GAS_TRANS_TBL_BIT) == 0)) {
98  l1rec->t_h2o[ipb] = water_vapor(ib, l1rec->wv[ip], airmass);
99  }
100 
101  }
102 
103  free(Taur);
104  free(rhor);
105  free(trup);
106  free(trdown);
107 
108  return (0);
109 }
110 
111 
112 /* ------------------------------------------------------------------------ */
113 /* Code below was provided by Jacques Descloitres, March 2000 */
114 /* ------------------------------------------------------------------------ */
115 
116 #define fac 0.0174532925199 /* PI/180 */
117 
118 void chand(float xphi, float xmuv, float xmus, float *xtau, float *rhoray, double *trup, double *trdown, int nbands) {
119  /*
120  input parameters: xphi,xmus,xmuv,xtau
121  xphi: azimuthal difference between sun and observation (xphi=0,
122  in backscattering) and expressed in degree (0.:360.)
123  xmus: cosine of the sun zenith angle
124  xmuv: cosine of the observation zenith angle
125  xtau: molecular optical depth
126  output parameter: xrray : molecular reflectance (0.:1.)
127  constant : xdep: depolarization factor (0.0279)
128  xfd = (1-xdep/(2-xdep)) / (1 + 2*xdep/(2-xdep)) = 2 * (1 - xdep) / (2 + xdep) = 0.958725775
129 
130  chAnged all instances of expf, logf, and cosf to exp, log, cos, to fix problems
131  with 64-bit solaris systems. BAF, 8/2002.
132  */
133  const double xfd = 0.958725775;
134  const float xbeta2 = 0.5;
135  float pl[5];
136  double fs01, fs02, fs0, fs1, fs2;
137  const float as0[10] = {0.33243832, 0.16285370, -0.30924818, -0.10324388, 0.11493334,
138  -6.777104e-02, 1.577425e-03, -1.240906e-02, 3.241678e-02, -3.503695e-02};
139  const float as1[2] = {.19666292, -5.439061e-02};
140  const float as2[2] = {.14545937, -2.910845e-02};
141  float phios, xcosf1, xcosf2, xcosf3;
142  float xph1, xph2, xph3, xitm1, xitm2;
143  float xlntau, xitot1, xitot2, xitot3;
144  int i, ib;
145 
146  phios = 180 - xphi;
147  xcosf1 = 1.;
148  xcosf2 = cos(phios * fac);
149  xcosf3 = cos(2 * phios * fac);
150  xph1 = 1 + (3 * xmus * xmus - 1) * (3 * xmuv * xmuv - 1) * xfd / 8.;
151  xph2 = -xfd * xbeta2 * 1.5 * xmus * xmuv * sqrt(1 - xmus * xmus) * sqrt(1 - xmuv * xmuv);
152  xph3 = xfd * xbeta2 * 0.375 * (1 - xmus * xmus) * (1 - xmuv * xmuv);
153  pl[0] = 1.;
154  pl[1] = xmus + xmuv;
155  pl[2] = xmus * xmuv;
156  pl[3] = xmus * xmus + xmuv * xmuv;
157  pl[4] = xmus * xmus * xmuv * xmuv;
158  fs01 = fs02 = 0;
159  for (i = 0; i < 5; i++) fs01 += pl[i] * as0[i];
160  for (i = 0; i < 5; i++) fs02 += pl[i] * as0[5 + i];
161  for (ib = 0; ib < nbands; ib++) {
162  xlntau = log(xtau[ib]);
163  fs0 = fs01 + fs02 * xlntau;
164  fs1 = as1[0] + xlntau * as1[1];
165  fs2 = as2[0] + xlntau * as2[1];
166  trdown[ib] = exp(-xtau[ib] / xmus);
167  trup[ib] = exp(-xtau[ib] / xmuv);
168  xitm1 = (1 - trdown[ib] * trup[ib]) / 4. / (xmus + xmuv);
169  xitm2 = (1 - trdown[ib]) * (1 - trup[ib]);
170  xitot1 = xph1 * (xitm1 + xitm2 * fs0);
171  xitot2 = xph2 * (xitm1 + xitm2 * fs1);
172  xitot3 = xph3 * (xitm1 + xitm2 * fs2);
173  rhoray[ib] = xitot1 * xcosf1 + xitot2 * xcosf2 * 2 + xitot3 * xcosf3 * 2;
174  }
175 
176 }
void chand(float xphi, float xmuv, float xmus, float *xtau, float *rhoray, double *trup, double *trdown, int nbands)
#define NULL
Definition: decode_rs.h:63
read l1rec
const double pi
float mu
instr * input
#define fac
float water_vapor
Definition: atrem_corl1.h:226
void gaseous_transmittance(l1str *l1rec, int32_t ip)
Definition: gas_trans.c:633
#define FATAL_ERROR
Definition: swl0_parms.h:5
int atmocor1_land(l1str *l1rec, int32_t ip)
Definition: atmocor1_land.c:20
int32_t nbands
#define GAS_TRANS_TBL_BIT
Definition: l12_parms.h:62
float mu0
#define SEAWIFS
Definition: sensorDefs.h:12
int i
Definition: decode_rs.h:71