OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
owt.c
Go to the documentation of this file.
1 #include "l12_proto.h"
2 #include "nr.h"
3 #include "nrutil.h"
4 
5 #define DEBUG_OWT 0
6 #define NCLASSES 16
7 #define NRRS 6
8 #define NWTS 9
9 
10 static float **owt;
11 static float **owtn;
12 static float *owtd;
13 static int nclass = NCLASSES;
14 static int nwts = NWTS;
15 static int lastScanRun = -1;
16 
17 //int fuzzy_func (float *rrs, float **urrs,float ***y3inv, int nclass, int df, double *outdata);
18 void fuzzy_func_v3(float *rrs, float **urrs, float ***y3inv, int nclass, int nwts, int df, double *outdata);
19 void covariance_inversion(float *rrs_cov, int nclasses, int df, float ***y3inv);
20 
21 /* ---------------------------------------------------------------------- */
22 
23 /* ---------------------------------------------------------------------- */
24 void run_owt(l2str *l2rec) {
25  static int firstCall = 1;
26  static int bindx[NRRS];
27  static int nrrs = NRRS;
28  static float badval = BAD_FLT;
29 
30  static float rrs[NRRS];
31  static float rrs_means[NRRS * NCLASSES];
32  static float rrs_cov[NCLASSES * NRRS * NRRS];
33 
34  static float **urrs;
35  static float ***y3inv;
36  static double outclass[NCLASSES];
37  static float *wave;
38 
39  float owt_sum;
40  float owt_max;
41  int status = 0;
42  int32_t ip, ib, ic, ipb;
43 
44  l1str *l1rec = l2rec->l1rec;
45  filehandle *l1file = l1rec->l1file;
46 
47  if (firstCall) {
48 
49  int32_t ic;
50  int32 sd_id, sds_id, i, j, k;
51  int32 dims1[2], start1[2], edge1[2];
52  int32 dims2[3], start2[3], edge2[3];
53  char fname[FILENAME_MAX];
54  char sdsname[H4_MAX_NC_NAME] = "";
55 
56  firstCall = 0;
57 
58  strcpy(fname, input->owtfile);
59  if (strlen(fname) == 0) {
60  printf("-E- %s line %d: No owtfile specified.\n", __FILE__, __LINE__);
61  exit(1);
62  }
63  printf("\nLoading optical class data from %s\n", fname);
64  sd_id = SDstart(fname, DFACC_RDWR);
65 
66  // sensor specifics
67  if ((wave = (float *) calloc(l1file->nbands, sizeof (float))) == NULL) {
68  printf("-E- : Error allocating memory to run_owt\n");
69  exit(FATAL_ERROR);
70  }
71 
72  switch (l1file->sensorID) {
73  case SEAWIFS:
74  nrrs = 5;
75  wave[0] = 412;
76  wave[1] = 443;
77  wave[2] = 490;
78  wave[3] = 510;
79  wave[4] = 555;
80  break;
81  case MODIST:
82  case MODISA:
83  nrrs = 4;
84  wave[0] = 412;
85  wave[1] = 443;
86  wave[2] = 490;
87  wave[3] = 550;
88  break;
89  default:
90  printf("%s Line %d: No classification data available for this sensor.\n", __FILE__, __LINE__);
91  break;
92  }
93 
94  // input band indicies
95  for (ib = 0; ib < nrrs; ib++)
96  bindx[ib] = windex(wave[ib], l1file->fwave, l1file->nbands);
97 
98  // static storage for results
99  urrs = matrix(1, nrrs, 1, nclass);
100  y3inv = f3tensor(1, nclass, 1, nrrs, 1, nrrs);
101  owt = allocate2d_float(l1rec->npix, nclass);
102  if (owt == NULL) {
103  printf("-E- %s line %d : error allocating memory for optical classes.\n",
104  __FILE__, __LINE__);
105  exit(1);
106  }
107  owtn = allocate2d_float(l1rec->npix, nclass);
108  if (owtn == NULL) {
109  printf("-E- %s line %d : error allocating memory for optical classes.\n",
110  __FILE__, __LINE__);
111  exit(1);
112  }
113  owtd = (float *) calloc(l1rec->npix, sizeof (float));
114  if (owtd == NULL) {
115  printf("-E- %s line %d : error allocating memory for optical classes.\n",
116  __FILE__, __LINE__);
117  exit(1);
118  }
119 
120  dims1 [0] = nrrs;
121  dims1 [1] = nclass;
122  start1 [0] = 0;
123  start1 [1] = 0;
124  edge1 [0] = dims1[0];
125  edge1 [1] = dims1[1];
126 
127  strcpy(sdsname, "class_means");
128  sds_id = SDselect(sd_id, SDnametoindex(sd_id, sdsname));
129  status = SDreaddata(sds_id, start1, NULL, edge1, (VOIDP) rrs_means);
130  if (status != 0) {
131  printf("-E- %s: Error reading SDS %s from %s.\n", __FILE__, sdsname, fname);
132  SDend(sd_id);
133  exit(1);
134  } else {
135  status = SDendaccess(sds_id);
136  }
137 
138  dims2 [0] = nclass;
139  dims2 [1] = nrrs;
140  dims2 [2] = nrrs;
141  start2 [0] = 0;
142  start2 [1] = 0;
143  start2 [2] = 0;
144  edge2 [0] = dims2[0];
145  edge2 [1] = dims2[1];
146  edge2 [2] = dims2[2];
147 
148  strcpy(sdsname, "class_covariance");
149  sds_id = SDselect(sd_id, SDnametoindex(sd_id, sdsname));
150  status = SDreaddata(sds_id, start2, NULL, edge2, (VOIDP) rrs_cov);
151  if (status != 0) {
152  printf("-E- %s: Error reading SDS %s from %s.\n", __FILE__, sdsname, fname);
153  SDend(sd_id);
154  exit(1);
155  } else {
156  status = SDendaccess(sds_id);
157  }
158 
159  for (ic = 0; ic < nclass; ic++)
160  for (ib = 0; ib < nrrs; ib++) {
161  urrs[ib + 1][ic + 1] = rrs_means[ib * nclass + ic];
162  }
163 
164  covariance_inversion(rrs_cov, nclass, nrrs, y3inv);
165 
166  if (DEBUG_OWT) {
167  printf("\n");
168  for (i = 0; i < nclass; i++) for (j = 0; j < nrrs; j++)
169  printf("urrs %d %d %f\n", j + 1, i + 1, urrs[j + 1][i + 1]);
170  printf("\n");
171  for (i = 0; i < nclass; i++) for (j = 0; j < nrrs; j++) for (k = 0; k < nrrs; k++)
172  printf("y3inv %d %d %d %f\n", i + 1, j + 1, k + 1, y3inv[i + 1][j + 1][k + 1]);
173  }
174  }
175 
176  for (ip = 0; ip < l1rec->npix; ip++) {
177 
178  ipb = ip * l1file->nbands;
179 
180  // initialize i/o arrays
181 
182  for (ic = 0; ic < nclass; ic++) {
183  owt [ip][ic] = badval;
184  owtn[ip][ic] = badval;
185  }
186  owtd[ip] = badval;
187 
188  status = 0;
189  for (ib = 0; ib < nrrs; ib++) {
190  rrs[ib] = rrs_above_to_below(l2rec->Rrs[ipb + bindx[ib]]) * l2rec->Rrs[ipb + bindx[ib]];
191  if (rrs[ib] < 0) status++;
192  if (DEBUG_OWT) printf("\nrrs %d %f %f", ib, rrs[ib], l2rec->Rrs[ipb + bindx[ib]]);
193  }
194 
195  // run classification and store
196  if (status == 0) {
197  // status = fuzzy_func(rrs,urrs,y3inv,nclass,nrrs,outclass);
198  fuzzy_func_v3(rrs, urrs, y3inv, nclass, nwts, nrrs, outclass);
199  if (status == 0) {
200  owt_sum = 0.0;
201  owt_max = BAD_FLT;
202  for (ic = 0; ic < nwts; ic++) {
203  if (outclass[ic] < 1e-35)
204  outclass[ic] = 0.0;
205  owt[ip][ic] = (float) outclass[ic];
206  owt_sum += owt[ip][ic];
207  if (DEBUG_OWT) printf("\n%d %d %f", ip, ic, outclass[ic]);
208  if (owt[ip][ic] > owt_max) {
209  owt_max = owt[ip][ic];
210  owtd[ip] = ic + 1;
211  }
212  }
213  for (ic = 0; ic < nwts; ic++) {
214  if (outclass[ic] >= 0.0)
215  owtn[ip][ic] = (float) outclass[ic] / owt_sum;
216  }
217  }
218 
219  }
220 
221  if (status != 0)
222  l1rec->flags[ip] |= PRODFAIL;
223  }
224 
225  lastScanRun = l1rec->iscan;
226 }
227 
228 
229 /* ---------------------------------------------------------------------- */
230 
231 /* ---------------------------------------------------------------------- */
232 typedef struct error_struc {
233  float rms;
234  float bias;
235  float perc;
236 } errstr;
237 
238 
239 /* ---------------------------------------------------------------------- */
240 
241 /* ---------------------------------------------------------------------- */
242 float chl_error(char *fname, float wts[], int nwts, int dclass) {
243  static int firstCall = 1;
244  static errstr *erec;
245  static float badval = BAD_FLT;
246  static float min_sum_wts = 1e-6;
247 
248  float perc, rms, bias;
249  float sum_wts;
250  int ic;
251 
252  if (firstCall) {
253 
254  FILE *fp;
255  char line [80];
256  int clss;
257 
258  if (strlen(fname) == 0) {
259  printf("-E- %s line %d: No owtchlerrfile specified.\n", __FILE__, __LINE__);
260  exit(1);
261  }
262  printf("\nLoading chl error table from %s\n", fname);
263 
264  if ((fp = fopen(fname, "r")) == NULL) {
265  fprintf(stderr,
266  "-E- %s line %d: unable to open %s for reading\n",
267  __FILE__, __LINE__, fname);
268  return (-1);
269  }
270 
271  if ((erec = (errstr *) malloc(nwts * sizeof (errstr))) == NULL) {
272  printf("-E- %s line %d: error allocating space for error rec.\n", __FILE__, __LINE__);
273  exit(1);
274  }
275 
276  ic = 0;
277  while (fgets(line, 80, fp)) {
278  if (line[0] == '#' || line[0] == '\n')
279  continue;
280  sscanf(line, "%d %f %f %f\n", &clss, &perc, &rms, &bias);
281  erec[ic].perc = perc;
282  erec[ic].bias = bias;
283  erec[ic].rms = rms;
284  ic++;
285  if (ic > nwts) break;
286  }
287 
288  if (ic != nwts) {
289  printf("-E- %s line %d: Number of weights (%d) does not match number of error records (%d) in %s\n",
290  __FILE__, __LINE__, nwts, ic, fname);
291  exit(1);
292  }
293 
294  firstCall = 0;
295  }
296 
297  sum_wts = 0.0;
298  if (erec[dclass - 1].perc > 0.0) { // if no stats for dominant class, bail
299  perc = 0.0;
300  bias = 0.0;
301  rms = 0.0;
302  for (ic = 0; ic < nwts; ic++) {
303  if (wts[ic] >= 0.0 && erec[ic].perc > 0.0) {
304  perc += (wts[ic] * erec[ic].perc);
305  bias += (wts[ic] * erec[ic].perc);
306  rms += (wts[ic] * erec[ic].perc);
307  sum_wts += wts[ic];
308  }
309  }
310  }
311 
312  if (sum_wts > min_sum_wts)
313  perc /= sum_wts;
314  else
315  perc = badval;
316 
317  return (perc);
318 }
319 
320 
321 
322 /* ------------------------------------------------------------------- */
323 
324 /* ------------------------------------------------------------------- */
325 void optical_water_type(l2str *l2rec, l2prodstr *p, void *vptr) {
326  int classID = p->prod_ix - 1;
327  int prodID = p->cat_ix;
328  float *fptr = vptr;
329  int32_t ip;
330 
331  l1str *l1rec = l2rec->l1rec;
332 
333  if (classID < 0 || classID > nwts) {
334  printf("%s line %d: there is no class member %d\n", __FILE__, __LINE__, classID + 1);
335  exit(1);
336  }
337 
338  if (l1rec->iscan != lastScanRun)
339  run_owt(l2rec);
340 
341  switch (prodID) {
342  case CAT_owt:
343  for (ip = 0; ip < l1rec->npix; ip++)
344  *fptr++ = owt[ip][classID];
345  break;
346  case CAT_owtn:
347  for (ip = 0; ip < l1rec->npix; ip++)
348  *fptr++ = owtn[ip][classID];
349  break;
350  case CAT_owtd:
351  for (ip = 0; ip < l1rec->npix; ip++)
352  *fptr++ = owtd[ip];
353  break;
354  case CAT_chl_owterr:
355  for (ip = 0; ip < l1rec->npix; ip++)
356  *fptr++ = chl_error(input->owtchlerrfile, &owt[ip][0], nwts, owtd[ip]);
357  break;
358  }
359 
360  return;
361 }
362 
363 
int32 l1file(int32 sdfid, int32 *nsamp, int32 *nscans, int16 *dtynum)
Definition: l1stat_chk.c:586
const int bindx[3]
Definition: DbLutNetcdf.cpp:28
void run_owt(l2str *l2rec)
Definition: owt.c:24
int j
Definition: decode_rs.h:73
void fuzzy_func_v3(float *rrs, float **urrs, float ***y3inv, int nclass, int nwts, int df, double *outdata)
Definition: fuzzy_func_v3.c:34
int status
Definition: l1_czcs_hdf.c:32
#define CAT_owtn
Definition: l2prod.h:240
float chl_error(char *fname, float wts[], int nwts, int dclass)
Definition: owt.c:242
#define CAT_owtd
Definition: l2prod.h:241
#define NULL
Definition: decode_rs.h:63
void optical_water_type(l2str *l2rec, l2prodstr *p, void *vptr)
Definition: owt.c:325
read l1rec
def bias(y, y_hat)
Definition: metrics.py:155
#define MODIST
Definition: sensorDefs.h:18
float ** matrix(long nrl, long nrh, long ncl, long nch)
Definition: nrutil.c:60
#define PRODFAIL
Definition: l2_flags.h:41
#define NRRS
Definition: owt.c:7
float rrs_above_to_below(float Rrs)
Definition: giop.c:1598
float rms
Definition: owt.c:233
instr * input
#define CAT_owt
Definition: l2prod.h:239
#define FATAL_ERROR
Definition: swl0_parms.h:5
float bias
Definition: owt.c:234
float *** f3tensor(long nrl, long nrh, long ncl, long nch, long ndl, long ndh)
Definition: nrutil.c:170
float perc
Definition: owt.c:235
#define BAD_FLT
Definition: jplaeriallib.h:19
void covariance_inversion(float *rrs_cov, int nclasses, int df, float ***y3inv)
#define DEBUG_OWT
Definition: owt.c:5
int windex(float wave, float twave[], int ntwave)
Definition: windex.c:73
#define NWTS
Definition: owt.c:8
float ** allocate2d_float(size_t h, size_t w)
Allocate a two-dimensional array of type float of a given size.
Definition: allocate2d.c:125
#define NCLASSES
Definition: owt.c:6
dimstruct dims2[(int) NC_MAX_DIMS]
Definition: nccmp.c:27
#define SEAWIFS
Definition: sensorDefs.h:12
dimstruct dims1[(int) NC_MAX_DIMS]
Definition: nccmp.c:27
int i
Definition: decode_rs.h:71
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
#define MODISA
Definition: sensorDefs.h:19
int k
Definition: decode_rs.h:73
#define CAT_chl_owterr
Definition: l2prod.h:242
float p[MODELMAX]
Definition: atrem_corl1.h:131