OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
goci_slot.c
Go to the documentation of this file.
1 
2 #include "hdf5.h"
3 #include "hdf5_hl.h"
4 #include <stdlib.h>
5 #include <string.h>
6 #include <math.h>
7 #include <proj.h>
8 #include "goci.h"
9 
10 #define NFIELDS (hsize_t) 28
11 #define NRECORDS (hsize_t) 128
12 #define NAV_GRP "HDFEOS/POINTS/Navigation for GOCI/Data"
13 #define TABLE_NAME "Navigation for GOCI"
14 
15 /* quick number sorter for qsort */
16 static int numcomp(const void *p1, const void *p2) {
17  return *(char *) p1 - *(char *) p2;
18 }
19 
20 int32_t goci_slot_init(hid_t file_id, hsize_t *dims, float *slot_rel_time,
21  unsigned char *slot_asg, int32_t *slot_nav_avail)
22 /*******************************************************************
23 
24  goci_slot_init
25 
26  purpose: set up tables to find the time for a pixel in a GOCI scene
27 
28  Returns type: int - 0 if all is OK
29 
30  Parameters: (in calling order)
31  Type Name I/O Description
32  ---- ---- --- -----------
33  hid_t file_id I ID of GOCI L1B file
34  int * dims I scene size in [ lines, pixels ]
35  float * slot_rel_time O table of relative time for the
36  unsigned char * slot_asg O size [# scene pixels, # scene
37  lines] esitmate of the slot
38  for each scene pixel
39  int32_t * slot_nav_avail O flag indicating if the slot
40  navigation is valid from this
41  L1B (a 1 if valid, 0 if not)
42 
43  Modification history:
44  Programmer Date Description of change
45  ---------- ---- ---------------------
46  W. Robinson, SAIC 26 Nov 2014 original development
47 
48  *******************************************************************/ {
49  slot_nav_str *slot_nav;
50  /*
51  * allocate storage for the table of slot nav info
52  * to be read from the data table: "Navigation for GOCI"
53  */
54  if ((slot_nav = (slot_nav_str *)
55  malloc(NRECORDS * sizeof ( slot_nav_str))) == NULL) {
56  printf("%s,%d-E Unable to allocate the slot navigation structure\n",
57  __FILE__, __LINE__);
58  return 1;
59  }
60 
61  /* Calculate the size and the offsets of our struct members in memory */
62  size_t nav_size = sizeof ( slot_nav_str);
63  size_t nav_offset[NFIELDS] = {HOFFSET(slot_nav_str, band_num),
64  HOFFSET(slot_nav_str, slot_num),
65  HOFFSET(slot_nav_str, rel_time),
66  HOFFSET(slot_nav_str, sc_att),
67  HOFFSET(slot_nav_str, xo),
68  HOFFSET(slot_nav_str, yo),
69  HOFFSET(slot_nav_str, xs),
70  HOFFSET(slot_nav_str, ys),
71  HOFFSET(slot_nav_str, xpo),
72  HOFFSET(slot_nav_str, ypo),
73  HOFFSET(slot_nav_str, xps),
74  HOFFSET(slot_nav_str, yps),
75  HOFFSET(slot_nav_str, num_a_parm),
76  HOFFSET(slot_nav_str, a_parm),
77  HOFFSET(slot_nav_str, num_b_parm),
78  HOFFSET(slot_nav_str, b_parm),
79  HOFFSET(slot_nav_str, num_c_parm),
80  HOFFSET(slot_nav_str, c_parm),
81  HOFFSET(slot_nav_str, num_d_parm),
82  HOFFSET(slot_nav_str, d_parm),
83  HOFFSET(slot_nav_str, num_ap_parm),
84  HOFFSET(slot_nav_str, ap_parm),
85  HOFFSET(slot_nav_str, num_bp_parm),
86  HOFFSET(slot_nav_str, bp_parm),
87  HOFFSET(slot_nav_str, num_cp_parm),
88  HOFFSET(slot_nav_str, cp_parm),
89  HOFFSET(slot_nav_str, num_dp_parm),
90  HOFFSET(slot_nav_str, dp_parm)};
91 
92  size_t nav_sizes[NFIELDS] = {sizeof ( slot_nav[0].band_num),
93  sizeof ( slot_nav[0].slot_num),
94  sizeof ( slot_nav[0].rel_time),
95  sizeof ( slot_nav[0].sc_att),
96  sizeof ( slot_nav[0].xo),
97  sizeof ( slot_nav[0].yo),
98  sizeof ( slot_nav[0].xs),
99  sizeof ( slot_nav[0].ys),
100  sizeof ( slot_nav[0].xpo),
101  sizeof ( slot_nav[0].ypo),
102  sizeof ( slot_nav[0].xps),
103  sizeof ( slot_nav[0].yps),
104  sizeof ( slot_nav[0].num_a_parm),
105  sizeof ( slot_nav[0].a_parm),
106  sizeof ( slot_nav[0].num_b_parm),
107  sizeof ( slot_nav[0].b_parm),
108  sizeof ( slot_nav[0].num_c_parm),
109  sizeof ( slot_nav[0].c_parm),
110  sizeof ( slot_nav[0].num_d_parm),
111  sizeof ( slot_nav[0].d_parm),
112  sizeof ( slot_nav[0].num_ap_parm),
113  sizeof ( slot_nav[0].ap_parm),
114  sizeof ( slot_nav[0].num_bp_parm),
115  sizeof ( slot_nav[0].bp_parm),
116  sizeof ( slot_nav[0].num_cp_parm),
117  sizeof ( slot_nav[0].cp_parm),
118  sizeof ( slot_nav[0].num_dp_parm),
119  sizeof ( slot_nav[0].dp_parm)};
120  /*
121  * goci slot navigation info end
122  */
123 
124  hid_t grp_id;
125  int32_t npix, nlin, step, nsx, nsy, trg_bnd, ix, iy;
126  int32_t itile, ipix, ilin, lin_st, lin_en, pix_st, pix_en;
127  hsize_t nfields, nrecords, nbnd, nslot;
128  unsigned char *slot_asg_sml, *bnd_tile_lut, curtil;
129  unsigned char box_pts[4];
130  float minrad, crad;
131  float min_t, max_t, rel_t;
132  int32_t ibnd, ilut;
133 
134  npix = dims[1];
135  nlin = dims[0];
136  nbnd = 8;
137  nslot = 16;
138  bnd_tile_lut = NULL;
139 
140  /*
141  * set to the group
142  */
143  if ((grp_id = H5Gopen1(file_id, NAV_GRP)) < 0) {
144  printf("%s,%d:E Unable to open group: %s\n", __FILE__, __LINE__, NAV_GRP);
145  return 1;
146  }
147  /*
148  * see if it has the fields, records expected
149  */
150  *slot_nav_avail = 0;
151  if (H5TBget_table_info(grp_id, TABLE_NAME, &nfields, &nrecords) < 0) {
152  printf("%s,%d:E Unable to get table info for: %s\n", __FILE__,
153  __LINE__, TABLE_NAME);
154  return 1;
155  }
156  printf("# fields: %d, # records: %d\n", (int) nfields, (int) nrecords);
157  if ((nfields != NFIELDS) || (nrecords != NRECORDS)) {
158  *slot_nav_avail = 0;
159  printf("%s,%d:W L1B GOCI input file\n does not have %d fields or %d records\n",
160  __FILE__, __LINE__, (int) NFIELDS, (int) NRECORDS);
161  } else {
162  *slot_nav_avail = 1;
163  /* read the table */
164  if (H5TBread_table(grp_id, TABLE_NAME, nav_size, nav_offset,
165  nav_sizes, slot_nav) < 0) {
166  printf("%s,%d:E Unable to read table info for: %s\n", __FILE__,
167  __LINE__, TABLE_NAME);
168  return 1;
169  }
170 
171  if (*slot_nav_avail == 1) {
172  /*
173  * next, make a super-grid generally defining the slot assignment
174  */
175  printf("Begin GOCI slot assignment\n");
176  step = 18; /* reduces calls to goci_slot_nav in super and full grid
177  steps for a 5k x 5k scene */
178  trg_bnd = 7;
179  nsx = 2 + npix / step;
180  nsy = 2 + nlin / step;
181  if ((slot_asg_sml = (unsigned char *)
182  malloc(nsx * nsy * sizeof ( unsigned char))) == NULL) {
183  printf("%s,%d:E Unable to allocate space for slot_asg_sml array\n",
184  __FILE__, __LINE__);
185  return 1;
186  H5Gclose(grp_id);
187  }
188  if ((bnd_tile_lut = (unsigned char *)
189  malloc(nbnd * nslot * sizeof ( unsigned char))) == NULL) {
190  printf("%s,%d:E Unable to allocate space for bnd_tile_lut array\n",
191  __FILE__, __LINE__);
192  H5Gclose(grp_id);
193  return 1;
194  ;
195  }
196  *bnd_tile_lut = 254;
197  for (iy = 0; iy < nsy; iy++) {
198  ilin = iy * step;
199  for (ix = 0; ix < nsx; ix++) {
200  ipix = ix * step;
201  minrad = 200.;
202  for (itile = 0; itile < 16; itile++) {
203  goci_slot_nav(ipix, ilin, trg_bnd, itile, slot_nav, nbnd, nslot,
204  bnd_tile_lut, &crad);
205  if (crad < minrad) {
206  *(slot_asg_sml + ix + nsx * iy) = itile;
207  minrad = crad;
208  }
209  }
210  }
211  }
212  printf("GOCI supergrid made, starting full slot assignment\n");
213  /*
214  * fill the full size slot assignment array
215  */
216  for (iy = 0; iy < (nsy - 1); iy++) {
217  lin_st = iy * step;
218  lin_en = (iy + 1) * step;
219  if (lin_en > nlin) lin_en = nlin;
220  for (ix = 0; ix < (nsx - 1); ix++) {
221  pix_st = ix * step;
222  pix_en = (ix + 1) * step;
223  if (pix_en > npix) pix_en = npix;
224  /*
225  * if the supergrid box has all the same slot, assign that value
226  * to the pixel, line range
227  */
228  box_pts[0] = *(slot_asg_sml + ix + nsx * iy);
229  box_pts[1] = *(slot_asg_sml + (ix + 1) + nsx * iy);
230  box_pts[2] = *(slot_asg_sml + ix + nsx * (iy + 1));
231  box_pts[3] = *(slot_asg_sml + (ix + 1) + nsx * (iy + 1));
232  qsort(box_pts, 4, sizeof ( char), numcomp);
233 
234  if (box_pts[0] == box_pts[3]) {
235  /*
236  * assign one tile type
237  */
238  for (ilin = lin_st; ilin < lin_en; ilin++)
239  for (ipix = pix_st; ipix < pix_en; ipix++)
240  *(slot_asg + ipix + npix * ilin) = box_pts[0];
241  } else {
242  /*
243  * step through each point and determine best slot
244  * using up to 4 candidate slots
245  */
246  for (ilin = lin_st; ilin < lin_en; ilin++) {
247  for (ipix = pix_st; ipix < pix_en; ipix++) {
248  minrad = 200.;
249  curtil = -1;
250  for (itile = 0; itile < 4; itile++) {
251  if (box_pts[itile] != curtil) {
252  curtil = box_pts[itile];
253  goci_slot_nav(ipix, ilin, trg_bnd, curtil, slot_nav,
254  nbnd, nslot, bnd_tile_lut, &crad);
255  if (crad < minrad) {
256  *(slot_asg + ipix + npix * ilin) = curtil;
257  minrad = crad;
258  }
259  }
260  }
261  }
262  }
263  }
264  /* for checkout, put in original supergrid point * 10 */
265  /*
266  *( slot_asg + pix_st + npix * lin_st ) =
267  *( slot_asg_sml + ix + nsx * iy ) * 10;
268  */
269  }
270  }
271  }
272  /*
273  * set up the time offsets per slot. As each band has a time offset, but
274  * we have no way to address individual bands, we'll use the mean of the
275  * band time range
276  */
277  /*
278  * loop thru slots and get each mean time from bands
279  */
280  for (itile = 0; itile < nslot; itile++) {
281  min_t = 5000.;
282  max_t = -5000.;
283  for (ibnd = 0; ibnd < nbnd; ibnd++) {
284  ilut = *(bnd_tile_lut + ibnd + nbnd * itile);
285  rel_t = slot_nav[ilut].rel_time;
286  if (rel_t > max_t) max_t = rel_t;
287  if (rel_t < min_t) min_t = rel_t;
288  }
289  slot_rel_time[itile] = (min_t + max_t) / 2.;
290  }
291  printf("GOCI slot, time assignments completed\n");
292  /* free space used and close the group */
293  free(slot_asg_sml);
294  free(bnd_tile_lut);
295  free(slot_nav);
296  }
297  H5Gclose(grp_id);
298 
299  return 0;
300 }
301 
302 int goci_slot_nav(int32_t ipix, int32_t ilin, int32_t bnd, int32_t itile,
303  slot_nav_str *slot_nav, int32_t nbnd, int32_t nslot,
304  unsigned char *bnd_tile_lut, float *lindist)
305 /*******************************************************************
306 
307  goci_slot_nav
308 
309  purpose: transform a goci scene point into the point on a specific tile
310  and return the largest linear normalized distance from the center
311 
312  Returns type: int - 0 if all is OK
313 
314  Parameters: (in calling order)
315  Type Name I/O Description
316  ---- ---- --- -----------
317  int32_t ipix I Pixel to transform
318  int32_t ilin I Line to transform
319  int32_t bnd I Band number
320  int32_t itile I Tile or slot number of GOCI
321  slot_nav_str *slot_nav I structure with transform
322  coefficients and normalization values
323  int32_t nbnd I number of bands
324  int32_t nslot I number of slots
325  unsigned char * bnd_tile_lut I/O storage for a look-up for
326  proper element in slot_nav
327  float * lindist O The largest normalized
328  linear distance from tile
329  center
330 
331  Modification history:
332  Programmer Date Description of change
333  ---------- ---- ---------------------
334  W. Robinson, SAIC 1 Dec 2014 original development
335  W. Robinson, SAIC 22 May 2017 switch criteria for slot choice from
336  minimum distance from center to minimum
337  linear distance from center
338 
339  *******************************************************************/ {
340 
341  int32_t ilut, nlut;
342  int i, num_a_parm, num_b_parm, num_c_parm, num_d_parm;
343  float xo, yo, xs, ys, *a_parm, *b_parm, *c_parm, *d_parm;
344  float dist;
345  double xn, yn, vec[16], xpn, ypn, numer, denom;
346 
347  /*
348  * set up the look-up to find proper slot, band
349  */
350  nlut = nbnd * nslot;
351  if (*bnd_tile_lut == 254) {
352  for (ilut = 0; ilut < nlut; ilut++)
353  *(bnd_tile_lut + slot_nav[ilut].band_num +
354  nbnd * slot_nav[ilut].slot_num) = ilut;
355  }
356  /*
357  * get normalization coefficients for scene to normalized scene
358  */
359  ilut = *(bnd_tile_lut + bnd + nbnd * itile);
360  xo = slot_nav[ilut].xo;
361  yo = slot_nav[ilut].yo;
362  xs = slot_nav[ilut].xs;
363  ys = slot_nav[ilut].ys;
364  /*
365  * for the transform: scene -> tile normalized
366  */
367  num_a_parm = slot_nav[ilut].num_a_parm;
368  a_parm = slot_nav[ilut].a_parm;
369  num_b_parm = slot_nav[ilut].num_b_parm;
370  b_parm = slot_nav[ilut].b_parm;
371  num_c_parm = slot_nav[ilut].num_c_parm;
372  c_parm = slot_nav[ilut].c_parm;
373  num_d_parm = slot_nav[ilut].num_d_parm;
374  d_parm = slot_nav[ilut].d_parm;
375  /*
376  * make normalized scene location
377  */
378  xn = ((double) ipix - (double) xo) / (double) xs;
379  yn = ((double) ilin - (double) yo) / (double) ys;
380  /*
381  * transform from scene to tile normalized
382  */
383  for (i = 0; i < nslot; i++)
384  vec[i] = 0.;
385  vec[0] = 1.;
386  vec[1] = xn;
387  vec[2] = yn;
388  vec[3] = xn * yn;
389  vec[4] = pow(xn, 2.);
390  vec[5] = pow(yn, 2.);
391  vec[6] = pow(xn, 2.) * yn;
392  vec[7] = pow(yn, 2.) * xn;
393  vec[8] = pow(yn, 2.) * pow(xn, 2.);
394  /* X */
395  for (i = 0, numer = 0.; i < num_a_parm; i++)
396  numer += vec[i] * a_parm[i];
397  for (i = 0, denom = 1.; i < num_b_parm; i++)
398  denom += vec[i + 1] * b_parm[i];
399 
400  xpn = numer / denom;
401 
402  /* Y */
403  for (i = 0, numer = 0.; i < num_c_parm; i++)
404  numer += vec[i] * c_parm[i];
405  for (i = 0, denom = 1.; i < num_d_parm; i++)
406  denom += vec[i + 1] * d_parm[i];
407 
408  ypn = numer / denom;
409  /*
410  * find the normalized radius *** OLD WAY
411  *nradsq = (float) ( pow( xpn, 2. ) + pow( ypn, 2. ) );
412  */
413  /*
414  * find the smallest distance of this point from the 4 edges and
415  * return 1 - this as the longest linear distance from the benter
416  */
417  *lindist = 200.;
418  /* +X edge */
419  dist = 1. - xpn;
420  *lindist = (dist < *lindist) ? dist : *lindist;
421  /* -X edge */
422  dist = 1. + xpn;
423  *lindist = (dist < *lindist) ? dist : *lindist;
424  /* +Y edge */
425  dist = 1. - ypn;
426  *lindist = (dist < *lindist) ? dist : *lindist;
427  /* -Y edge */
428  dist = 1. + ypn;
429  *lindist = (dist < *lindist) ? dist : *lindist;
430 
431  /* Make it a distance from center */
432  *lindist = 1. - *lindist;
433  return 0;
434 }
435 
436 unsigned char goci_slot_time(int32_t ipix, int32_t ilin, goci_l1b_t *goci_l1b,
437  float *rel_sec)
438 /*******************************************************************
439 
440  goci_slot_time
441 
442  purpose: return the scene start relative time given a GOCI pixel, line
443 
444  Returns type: int - 0 if all is OK
445 
446  Parameters: (in calling order)
447  Type Name I/O Description
448  ---- ---- --- -----------
449  int32_t ipix I Pixel to transform
450  int32_t ilin I Line to transform
451  goci_l1b_t * goci_l1b I GOCI information structure
452  float * rel_sec O mean time of the pixel
453  relative to scene start time
454 
455  Modification history:
456  Programmer Date Description of change
457  ---------- ---- ---------------------
458  W. Robinson, SAIC 10 Dec 2014 original development
459 
460  *******************************************************************/ {
461  unsigned char p_slot;
462 
463  p_slot = *(goci_l1b->slot_asg + ipix + goci_l1b->npixels * ilin);
464 
465  *rel_sec = *(goci_l1b->slot_rel_time + p_slot);
466  return p_slot;
467 }
#define NFIELDS
Definition: goci_slot.c:10
int16_t * denom[MAXNFILES]
Definition: l2bin.cpp:99
#define NULL
Definition: decode_rs.h:63
#define NRECORDS
Definition: goci_slot.c:11
#define NAV_GRP
Definition: goci_slot.c:12
int nlin
Definition: get_cmp.c:28
subroutine sc_att(gaclac, tlm, navqc, att_ang, attangfl, iret)
Definition: sc_att.f:3
int nbnd
Definition: get_cmp.c:29
#define TABLE_NAME
Definition: goci_slot.c:13
float * slot_rel_time
Definition: goci.h:33
int goci_slot_nav(int32_t ipix, int32_t ilin, int32_t bnd, int32_t itile, slot_nav_str *slot_nav, int32_t nbnd, int32_t nslot, unsigned char *bnd_tile_lut, float *lindist)
Definition: goci_slot.c:302
integer, parameter double
GOCI file format reader.
int16_t * numer[MAXNFILES]
Definition: l2bin.cpp:99
unsigned char * slot_asg
Definition: goci.h:34
int32_t goci_slot_init(hid_t file_id, hsize_t *dims, float *slot_rel_time, unsigned char *slot_asg, int32_t *slot_nav_avail)
Definition: goci_slot.c:20
unsigned char goci_slot_time(int32_t ipix, int32_t ilin, goci_l1b_t *goci_l1b, float *rel_sec)
Definition: goci_slot.c:436
int i
Definition: decode_rs.h:71
int npixels
Definition: goci.h:16
int npix
Definition: get_cmp.c:27