OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
get_owmc.c
Go to the documentation of this file.
1 #include <stdlib.h>
2 #include <assert.h>
3 #include "l12_proto.h"
4 
5 static int lutLoaded = 0;
6 
7 // scale factors from lut file
8 static float scale_551;
9 static float offset_551;
10 static float scale_488;
11 static float offset_488;
12 static float scale_sst;
13 static float offset_sst;
14 
15 // actual lut file
16 static int32_t lut_num_rows = 0;
17 static float *lut_nlw_551;
18 static float *lut_nlw_488;
19 static float *lut_sst;
20 static int16_t *lut_class_ward;
21 static int16_t *lut_class_k;
22 static int16_t *lut_class_34k_w;
23 
24 // products for current scan line
25 static int32_t current_iscan = -1;
26 static float *class_ward;
27 static float *class_k;
28 static float *class_34k_w;
29 
30 static int ib551 = -1;
31 static int ib488 = -1;
32 
33 void init_owmc(l2str *l2rec) {
34  char titleStr[256] = "";
35 
36  int32 sd_id;
37  int32 status;
38  int32 dims[H4_MAX_VAR_DIMS];
39 
40  int32_t ip;
41  int32_t ipb;
42  int32_t row;
43 
44  float delta;
45  float best_delta;
46  int32_t best_lut_row;
47 
48  float raw_551;
49  float raw_488;
50  float raw_sst;
51 
52  float cooked_551;
53  float cooked_488;
54  float cooked_sst;
55 
56  l1str *l1rec = l2rec->l1rec;
57 
58  if (!lutLoaded) {
59 
60  printf("Loading OWMC lut file %s.\n", input->owmcfile);
61 
62  /* Open the file and initiate the SD interface */
63  sd_id = SDstart(input->owmcfile, DFACC_RDONLY);
64  if (sd_id == -1) {
65  fprintf(stderr, "-E- %s line %d: Could not open OWMC lut file %s.\n",
66  __FILE__, __LINE__, input->owmcfile);
67  exit(1);
68  }
69 
70  // Read the attribute data.
71  READ_GLBL_ATTR_E("Title", titleStr);
72 
73  // read title OK
74  if (strcmp(titleStr, "OWMC LUT") != 0) {
75  fprintf(stderr, "-E- %s line %d: Global attribute \"Title\" from %s should be \"OWMC LUT\".\n",
76  __FILE__, __LINE__, input->owmcfile);
77  exit(1);
78  }
79 
80  // Read the attribute data.
81  READ_GLBL_ATTR_E("scale_551", &scale_551);
82  READ_GLBL_ATTR_E("offset_551", &offset_551);
83  READ_GLBL_ATTR_E("scale_488", &scale_488);
84  READ_GLBL_ATTR_E("offset_488", &offset_488);
85  READ_GLBL_ATTR_E("scale_sst", &scale_sst);
86  READ_GLBL_ATTR_E("offset_sst", &offset_sst);
87 
88  status = getDims(sd_id, "nlw_551", dims);
89  if (status) {
90  fprintf(stderr, "-E- %s line %d: Could get dimensions for \"nlw_551\" from, %s.\n",
91  __FILE__, __LINE__, input->owmcfile);
92  exit(1);
93  }
94  lut_num_rows = dims[0];
95 
96  // allocate the memory for the lut
97  lut_nlw_551 = (float*) malloc(lut_num_rows * sizeof (float));
98  assert(lut_nlw_551);
99  lut_nlw_488 = (float*) malloc(lut_num_rows * sizeof (float));
100  assert(lut_nlw_488);
101  lut_sst = (float*) malloc(lut_num_rows * sizeof (float));
102  assert(lut_sst);
103 
104  lut_class_ward = (int16_t *) malloc(lut_num_rows * sizeof (int16_t));
105  assert(lut_class_ward);
106  lut_class_k = (int16_t *) malloc(lut_num_rows * sizeof (int16_t));
107  assert(lut_class_k);
108  lut_class_34k_w = (int16_t *) malloc(lut_num_rows * sizeof (int16_t));
109  assert(lut_class_34k_w);
110 
111  // allocate memory for the current line
112  class_ward = (float *) malloc(l1rec->npix * sizeof (float));
113  assert(class_ward);
114  class_k = (float *) malloc(l1rec->npix * sizeof (float));
115  assert(class_k);
116  class_34k_w = (float *) malloc(l1rec->npix * sizeof (float));
117  assert(class_34k_w);
118 
119  // read in the lut data
120  READ_SDS_E("nlw_551", lut_nlw_551, 0, 0, 0, lut_num_rows, 1, 1);
121  READ_SDS_E("nlw_488", lut_nlw_488, 0, 0, 0, lut_num_rows, 1, 1);
122  READ_SDS_E("sst", lut_sst, 0, 0, 0, lut_num_rows, 1, 1);
123  READ_SDS_E("class_ward", lut_class_ward, 0, 0, 0, lut_num_rows, 1, 1);
124  READ_SDS_E("class_k", lut_class_k, 0, 0, 0, lut_num_rows, 1, 1);
125  READ_SDS_E("class_34k_w", lut_class_34k_w, 0, 0, 0, lut_num_rows, 1, 1);
126 
127  /* Close the file */
128  status = SDend(sd_id);
129  if (status == FAIL) {
130  fprintf(stderr, "-E- %s line %d: Could not close OWMC lut file %s.\n",
131  __FILE__, __LINE__, input->owmcfile);
132  exit(1);
133  }
134 
135  // setup the band indexes for the sensor
136  if ((ib551 = bindex_get(545)) < 0)
137  if ((ib551 = bindex_get(550)) < 0)
138  if ((ib551 = bindex_get(555)) < 0)
139  if ((ib551 = bindex_get(560)) < 0) {
140  printf("-E- %s line %d: can't find 551 band\n", __FILE__, __LINE__);
141  exit(1);
142  }
143 
144  if ((ib488 = bindex_get(488)) < 0) {
145  printf("-E- %s line %d: can't find 488 band\n", __FILE__, __LINE__);
146  exit(1);
147  }
148 
149  lutLoaded = 1;
150  }
151 
152  // if the current scan line changed
153  // load up the products for the current line
154  if (l1rec->iscan != current_iscan) {
155  current_iscan = l1rec->iscan;
156 
157  // loop pixels
158  for (ip = 0; ip < l1rec->npix; ip++) {
159  ipb = ip * l1rec->l1file->nbands;
160 
161  raw_551 = l2rec->nLw[ipb + ib551];
162  raw_488 = l2rec->nLw[ipb + ib488];
163 
164  // check for missing values
165  if ((raw_551 != BAD_FLT) && (raw_551 != BAD_FLT)) {
166  if (l2rec->sst && (l2rec->sst[ip] > -2.0))
167  raw_sst = l2rec->sst[ip];
168  else
169  raw_sst = l1rec->sstref[ip];
170 
171  cooked_551 = (raw_551 - offset_551) / scale_551;
172  cooked_488 = (raw_488 - offset_488) / scale_488;
173  cooked_sst = (raw_sst - offset_sst) / scale_sst;
174 
175  best_delta = fabsf(cooked_551 - lut_nlw_551[0]) +
176  fabsf(cooked_488 - lut_nlw_488[0]) +
177  fabsf(cooked_sst - lut_sst[0]);
178  best_lut_row = 0;
179 
180  // loop through lut
181  for (row = 1; row < lut_num_rows; row++) {
182  delta = fabsf(cooked_551 - lut_nlw_551[row]) +
183  fabsf(cooked_488 - lut_nlw_488[row]) +
184  fabsf(cooked_sst - lut_sst[row]);
185  if (delta < best_delta) {
186  best_delta = delta;
187  best_lut_row = row;
188  }
189  } // for lut row
190 
191  class_ward[ip] = lut_class_ward[best_lut_row];
192  class_k[ip] = lut_class_k[best_lut_row];
193  class_34k_w[ip] = lut_class_34k_w[best_lut_row];
194  } else {
195  class_ward[ip] = BAD_FLT;
196  class_k[ip] = BAD_FLT;
197  class_34k_w[ip] = BAD_FLT;
198  }
199 
200  } // for pixel
201  } // if scan line changed
202 }
203 
204 float *get_class_ward_owmc(l2str *l2rec) {
205  init_owmc(l2rec);
206  return class_ward;
207 }
208 
209 float *get_class_k_owmc(l2str *l2rec) {
210  init_owmc(l2rec);
211  return class_k;
212 }
213 
214 float *get_class_34k_w_owmc(l2str *l2rec) {
215  init_owmc(l2rec);
216  return class_34k_w;
217 }
#define READ_SDS_E(nam, ptr, s0, s1, s2, e0, e1, e2)
Definition: hdf4utils.h:96
int status
Definition: l1_czcs_hdf.c:32
#define FAIL
Definition: ObpgReadGrid.h:18
read l1rec
float * get_class_34k_w_owmc(l2str *l2rec)
Definition: get_owmc.c:214
instr * input
int getDims(int32_t fileID, const char sdsname[], int32_t dims[])
int bindex_get(int32_t wave)
Definition: windex.c:45
const double delta
#define BAD_FLT
Definition: jplaeriallib.h:19
void init_owmc(l2str *l2rec)
Definition: get_owmc.c:33
#define READ_GLBL_ATTR_E(nam, ptr)
Definition: hdf4utils.h:75
float * get_class_k_owmc(l2str *l2rec)
Definition: get_owmc.c:209
float * get_class_ward_owmc(l2str *l2rec)
Definition: get_owmc.c:204