OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
virtual_constellation.c
Go to the documentation of this file.
1 #include "l12_proto.h"
2 #include "chl.h"
3 #include "fann.h"
4 
5 #define NBANDS_VC 7
6 static int wave_vc[] = {412, 443, 490, 510, 531, 555, 670};
7 static float badval = BAD_FLT;
8 static float Rrs_norm = 0.025;
9 static float ratio_531_norm = 2.;
10 
11 float Rrs_vc_seawifs(l2str *l2rec, int32_t ip, int32_t ibvc) {
12  static int firstCall = 1;
13 
14  int ib;
15  int ipb = ip * l2rec->l1rec->l1file->nbands;
16  static int iwave_nn[] = {412, 443, 490, 510, 555, 670};
17  float *Rrs = &l2rec->Rrs[ipb];
18  fann_type Rrs_in[4];
19  float Rrs_vc = badval;
20 
21  static struct fann *nntab;
22 
23  if (firstCall) {
24  // load tables
25  char nnFile [FILENAME_MAX] = "";
26  sprintf(nnFile, "%s%s%d%s", input->vcnnfile, "_", wave_vc[4], ".dat");
27  nntab = fann_create_from_file(nnFile);
28  firstCall = 0;
29  }
30 
31  // build NN input Rrs
32  for (ib = 1; ib < 5; ib++) {
33  ipb = ip * l2rec->l1rec->l1file->nbands + bindex_get(iwave_nn[ib]);
34  Rrs_in[ib - 1] = l2rec->Rrs[ipb] / Rrs_norm;
35  }
36 
37  // call conversion function
38 
39  switch (wave_vc[ibvc]) {
40  case 412:
41  Rrs_vc = Rrs[0];
42  break;
43  case 443:
44  Rrs_vc = Rrs[1];
45  break;
46  case 490:
47  Rrs_vc = Rrs[2];
48  break;
49  case 510:
50  Rrs_vc = Rrs[3];
51  break;
52  case 531:
53  Rrs_vc = (float) *fann_run(nntab, Rrs_in) * ratio_531_norm * Rrs[1];
54  break;
55  case 555:
56  Rrs_vc = Rrs[4];
57  break;
58  case 670:
59  Rrs_vc = Rrs[5];
60  break;
61  }
62 
63  return (Rrs_vc);
64 }
65 
66 float Rrs_vc_modisa(l2str *l2rec, int32_t ip, int32_t ibvc) {
67  static int firstCall = 1;
68  static int nband_nn = 7;
69  static int iwave_nn[] = {412, 443, 488, 531, 547, 667};
70  static struct fann * nntab[NBANDS_VC];
71 
72  int ib;
73  int ipb;
74  fann_type *Rrs_in;
75  float Rrs_vc = badval;
76 
77  if ((Rrs_in = (fann_type *) calloc(l2rec->l1rec->l1file->nbands, sizeof (fann_type))) == NULL) {
78  printf("-E- : Error allocating memory to Rrs_vc_modisa\n");
79  exit(FATAL_ERROR);
80  }
81 
82  if (firstCall) {
83  // load tables
84  char nnFile [FILENAME_MAX] = "";
85  for (ib = 0; ib < nband_nn; ib++) {
86  sprintf(nnFile, "%s%s%d%s", input->vcnnfile, "_", wave_vc[ib], ".dat");
87  nntab[ib] = fann_create_from_file(nnFile);
88  }
89  firstCall = 0;
90  }
91 
92  // build NN input Rrs
93  for (ib = 0; ib < nband_nn - 1; ib++) {
94  ipb = ip * l2rec->l1rec->l1file->nbands + bindex_get(iwave_nn[ib]);
95  Rrs_in[ib] = l2rec->Rrs[ipb] / Rrs_norm;
96  ;
97  }
98 
99  // call conversion function
100 
101  switch (wave_vc[ibvc]) {
102  case 412:
103  case 443:
104  case 490:
105  case 510:
106  case 555:
107  case 670:
108  Rrs_vc = (float) *fann_run(nntab[ibvc], Rrs_in);
109  Rrs_vc *= Rrs_norm;
110  break;
111  case 531:
112  Rrs_vc = Rrs_in[3] / Rrs_in[1];
113  Rrs_vc *= (float) *fann_run(nntab[ibvc], Rrs_in);
114  Rrs_vc *= Rrs_norm;
115  break;
116  }
117  free(Rrs_in);
118  return (Rrs_vc);
119 }
120 
121 float Rrs_vc_modist(l2str *l2rec, int32_t ip, int32_t ibvc) {
122  static int firstCall = 1;
123  static int nband_nn = 7;
124  static int iwave_nn[] = {412, 443, 488, 531, 547, 667};
125  static struct fann * nntab[NBANDS_VC];
126 
127  int ib;
128  int ipb;
129  fann_type *Rrs_in;
130  float Rrs_vc = badval;
131 
132  if (firstCall) {
133  // load tables
134  char nnFile [FILENAME_MAX] = "";
135  for (ib = 0; ib < nband_nn; ib++) {
136  sprintf(nnFile, "%s%s%d%s", input->vcnnfile, "_", wave_vc[ib], ".dat");
137  nntab[ib] = fann_create_from_file(nnFile);
138  }
139  firstCall = 0;
140  }
141  if ((Rrs_in = (fann_type *) calloc(l2rec->l1rec->l1file->nbands, sizeof (fann_type))) == NULL) {
142  printf("-E- %s line %d : error allocating memory for Rrs_in in Rrs_vc_modist.\n",
143  __FILE__, __LINE__);
144  exit(1);
145  }
146 
147  // build NN input Rrs
148  for (ib = 0; ib < nband_nn - 1; ib++) {
149  ipb = ip * l2rec->l1rec->l1file->nbands + bindex_get(iwave_nn[ib]);
150  Rrs_in[ib] = l2rec->Rrs[ipb] / Rrs_norm;
151  ;
152  }
153 
154  // call conversion function
155 
156  switch (wave_vc[ibvc]) {
157  case 412:
158  case 443:
159  case 490:
160  case 510:
161  case 555:
162  case 670:
163  Rrs_vc = (float) *fann_run(nntab[ibvc], Rrs_in);
164  Rrs_vc *= Rrs_norm;
165  break;
166  case 531:
167  Rrs_vc = Rrs_in[3] / Rrs_in[1];
168  Rrs_vc *= (float) *fann_run(nntab[ibvc], Rrs_in);
169  Rrs_vc *= Rrs_norm;
170  break;
171  }
172 
173  free(Rrs_in);
174  return (Rrs_vc);
175 }
176 
177 float Rrs_vc_viirs(l2str *l2rec, int32_t ip, int32_t ibvc) {
178  static int firstCall = 1;
179  static int nband_nn = 7;
180  static int iwave_nn[] = {410, 443, 486, 551, 671};
181  static struct fann * nntab[NBANDS_VC];
182 
183  int ib;
184  int ipb;
185  fann_type *Rrs_in;
186  fann_type Rrs_531_in[4];
187 
188  float Rrs_vc = badval;
189 
190  if (firstCall) {
191  // load tables
192  char nnFile [FILENAME_MAX] = "";
193  for (ib = 0; ib < nband_nn; ib++) {
194  sprintf(nnFile, "%s%s%d%s", input->vcnnfile, "_", wave_vc[ib], ".dat");
195  nntab[ib] = fann_create_from_file(nnFile);
196  }
197  firstCall = 0;
198  }
199  if ((Rrs_in = (fann_type *) calloc(l2rec->l1rec->l1file->nbands, sizeof (fann_type))) == NULL) {
200  printf("-E- %s line %d : error allocating memory for Rrs_in in Rrs_vc_modist.\n",
201  __FILE__, __LINE__);
202  exit(1);
203  }
204 
205  // build NN input Rrs
206  for (ib = 0; ib < nband_nn - 2; ib++) {
207  ipb = ip * l2rec->l1rec->l1file->nbands + bindex_get(iwave_nn[ib]);
208  Rrs_in[ib] = l2rec->Rrs[ipb] / Rrs_norm;
209  if (ib > 0 && ib < 5)
210  Rrs_531_in[ib - 1] = l2rec->Rrs[ipb] / Rrs_norm;
211  }
212 
213  // call conversion function
214 
215  switch (wave_vc[ibvc]) {
216  case 412:
217  case 443:
218  case 490:
219  case 510:
220  case 555:
221  case 670:
222  Rrs_vc = (float) *fann_run(nntab[ibvc], Rrs_in) * Rrs_norm;
223  break;
224  case 531:
225  Rrs_vc = (float) *fann_run(nntab[1], Rrs_in) * Rrs_norm;
226  Rrs_vc *= (float) *fann_run(nntab[ibvc], Rrs_531_in) * ratio_531_norm;
227  break;
228  }
229  free(Rrs_in);
230  return (Rrs_vc);
231 }
232 
233 float Rrs_vc_convert(l2str *l2rec, int ip, int ib) {
234  switch (l2rec->l1rec->l1file->sensorID) {
235  case SEAWIFS:
236  return (Rrs_vc_seawifs(l2rec, ip, ib));
237  break;
238  break;
239  case MODISA:
240  return (Rrs_vc_modisa(l2rec, ip, ib));
241  break;
242  break;
243  case MODIST:
244  return (Rrs_vc_modist(l2rec, ip, ib));
245  break;
246  break;
247  case VIIRSN:
248  case VIIRSJ1:
249  return (Rrs_vc_viirs(l2rec, ip, ib));
250  break;
251  break;
252  default:
253  printf("%s Line %d: VC Rrs conversion not defined for this sensor.\n", __FILE__, __LINE__);
254  exit(1);
255  break;
256  }
257 }
258 
259 float chl_vc(l2str *l2rec, int32_t ip) {
260  static int firstCall = 1;
261  static float a[] = {0.2515, -2.3798, 1.5823, -0.6372, -0.5692};
262  static int ib1 = 1; // 443
263  static int ib2 = 2; // 490
264  static int ib3 = 5; // 555
265 
266  float rat, minRrs;
267  float Rrs1, Rrs2, Rrs3;
268  float chl = chlbad;
269 
270  if (firstCall) {
271  firstCall = 0;
272  }
273 
274  /* */
275  /* Compute desired products at each pixel */
276  /* */
277  Rrs1 = Rrs_vc_convert(l2rec, ip, ib1);
278  Rrs2 = Rrs_vc_convert(l2rec, ip, ib2);
279  Rrs3 = Rrs_vc_convert(l2rec, ip, ib3);
280 
281  minRrs = MIN(Rrs1, Rrs2);
282 
283  if (Rrs3 > 0.0 && Rrs2 > 0.0 && minRrs > -0.001) {
284  rat = MAX(Rrs1, Rrs2) / Rrs3;
285  if (rat > minrat && rat < maxrat) {
286  rat = log10(rat);
287  chl = (float) pow(10.0, (a[0] + rat * (a[1] + rat * (a[2] + rat * (a[3] + rat * a[4])))));
288  chl = (chl > chlmin ? chl : chlmin);
289  chl = (chl < chlmax ? chl : chlmax);
290  }
291  }
292 
293  return (chl);
294 }
295 
296 void virtual_constellation(l2str *l2rec, l2prodstr *p, float prod[]) {
297  int32_t prodnum = p->cat_ix;
298  int32_t ibvc = p->prod_ix;
299  int32_t ip;
300 
301  /* */
302  /* Compute desired products at each pixel */
303  /* */
304  for (ip = 0; ip < l2rec->l1rec->npix - 1; ip++) {
305  switch (prodnum) {
306  case CAT_Rrs_vc:
307  prod[ip] = Rrs_vc_convert(l2rec, ip, ibvc);
308  break;
309  case CAT_chl_vc:
310  prod[ip] = chl_vc(l2rec, ip);
311  break;
312  }
313  }
314 
315 }
#define MAX(A, B)
Definition: swl0_utils.h:26
#define MIN(x, y)
Definition: rice.h:169
float Rrs_vc_seawifs(l2str *l2rec, int32_t ip, int32_t ibvc)
float Rrs_vc_convert(l2str *l2rec, int ip, int ib)
float chl_vc(l2str *l2rec, int32_t ip)
float Rrs_vc_viirs(l2str *l2rec, int32_t ip, int32_t ibvc)
#define NULL
Definition: decode_rs.h:63
#define VIIRSN
Definition: sensorDefs.h:23
#define MODIST
Definition: sensorDefs.h:18
#define CAT_chl_vc
Definition: l2prod.h:260
instr * input
int bindex_get(int32_t wave)
Definition: windex.c:45
#define NBANDS_VC
#define FATAL_ERROR
Definition: swl0_parms.h:5
#define BAD_FLT
Definition: jplaeriallib.h:19
void virtual_constellation(l2str *l2rec, l2prodstr *p, float prod[])
#define CAT_Rrs_vc
Definition: l2prod.h:259
float Rrs_vc_modist(l2str *l2rec, int32_t ip, int32_t ibvc)
float Rrs_vc_modisa(l2str *l2rec, int32_t ip, int32_t ibvc)
#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
#define MODISA
Definition: sensorDefs.h:19
#define VIIRSJ1
Definition: sensorDefs.h:37
float p[MODELMAX]
Definition: atrem_corl1.h:131