OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
chk_sds.c
Go to the documentation of this file.
1 //#ifndef LINUX
2 //#include <ieeefp.h>
3 //#endif
4 
5 #include <math.h>
6 
7 #include "fmt_check.h"
8 extern int verbose; /* 0 - don't print info on each vgroup, 1 do */
9 extern int fmt_status; /* status of format check, see fmt_check */
10 
11 int chk_sds(int32 fid, fmt_str *fmt, int isds)
12 /*******************************************************************
13 
14  chk_sds
15 
16  purpose: for a particular science dataset, check the existance of it
17  in the dataset and make sure it has the specified
18  attributes and that the type and ranges of the dataset are
19  correct.
20 
21  Returns type: int - 0 if all went well,
22 
23  Parameters: (in calling order)
24  Type Name I/O Description
25  ---- ---- --- -----------
26  int32 fid I file id or sds id
27  fmt_str * fmt I format description struct
28  int isds I index of the current SDS
29  being checked
30 
31  Modification history:
32  Programmer Date Description of change
33  ---------- ---- ---------------------
34  W. Robinson 18-Feb-1995 Original development
35  W. Robinson 30-Jun-1995 set fmt_status if problems
36  W. Robinson 4-Oct-1995 add a return of the actual count of
37  attr items read
38  W. Robinson 1-Oct-1996 add optional checking of SDS contents
39  within min / max range
40  W. Robinson 31-Oct-1996 upgrade to handle float64 data values
41  W. Robinson 31-May-2000 check for NaN in floats and not finite
42  in doubles
43  W. Robinson 15-Mar-2001 update with sone linux changes libraries
44  W. Robinson, SAIC 31 Mar 2005 changes for the table driven version
45 
46  *******************************************************************/
47  {
48  int32 ind, i, erng, dimsiz, a_rank, a_type, a_range[4], a_nattr,
49  sds_id, index, irem, icount, tot_pts, start[4], *ptr_i32;
50  char range_str[50], s_range_str[100];
51  void *ptr;
52  float32 *ptr_f32;
53  float64 *ptr_f64;
54  int16 *ptr_i16;
55  int8 *ptr_i8;
56  uint8 *ptr_ui8;
57  int a_count;
58  u_data value;
59  s_data s_range; /* actual sds range found (if looking) */
60  sds_info_str cur_sds; /* current SDS being looked at */
61 
62  /*
63  * get the current SDS for convenience
64  */
65  cur_sds = fmt->sds_info[isds];
66 
67  /*
68  * get the index for the science dataset
69  */
70  if ((index = SDnametoindex(fid, cur_sds.name)) < 0) {
71  printf("**** SDS: '%s' cannot be located in the file\n",
72  cur_sds.name);
73  fmt_status = fmt_status | 2;
74  return -1;
75  }
76  /*
77  * next, get the sds id
78  */
79  if ((sds_id = SDselect(fid, index)) < 0) {
80  printf("**** SDS: '%s', cannot get the ID from index\n",
81  cur_sds.name);
82  fmt_status = fmt_status | 2;
83  return -1;
84  }
85  /*
86  * next, find out about the dataset and check with expectations
87  */
88  if (SDgetinfo(sds_id, NULL, &a_rank, a_range, &a_type, &a_nattr)
89  != 0) {
90  printf("**** SDS: '%s', Unable to read the info on SDS\n",
91  cur_sds.name);
92  fmt_status = fmt_status | 2;
93  }
94 
95  if (a_rank != cur_sds.rank) {
96  printf("**** SDS: '%s', Mismatch in the rank\n", cur_sds.name);
97  printf("expected: %d, read: %d\n", cur_sds.rank, a_rank);
98  fmt_status = fmt_status | 2;
99  }
100 
101  for (i = 0; i < a_rank; i++) {
102  erng = cur_sds.e_ranges[i];
103  if (erng != 0) /* if we need to check dimensions... */ {
104  /*
105  * get the dimension size: erng if > 0, dimension struct entry if < 0
106  */
107  dimsiz = (erng > 0) ? erng : fmt->dim_id[ (-erng) - 1 ].dim_size;
108 
109  if (a_range[i] != dimsiz) {
110  printf("**** SDS: '%s', Mismatch in length of dim # %d\n",
111  cur_sds.name, i);
112  printf("expected: %d, read: %d\n", dimsiz, a_range[i]);
113  fmt_status = fmt_status | 2;
114  }
115  }
116  }
117  if (a_type != cur_sds.type) {
118  printf("**** SDS: '%s', Mismatch data type\n", cur_sds.name);
119  printf("expected: %d, read: %d\n", cur_sds.type,
120  a_type);
121  fmt_status = fmt_status | 2;
122  }
123  if ((cur_sds.n_attr >= 0) && (a_nattr != cur_sds.n_attr)) {
124  printf("**** SDS: '%s', Mismatch in # attributes for sds\n",
125  cur_sds.name);
126  printf("expected: %d, read: %d\n", cur_sds.n_attr, a_nattr);
127  fmt_status = fmt_status | 2;
128  }
129 
130  /*
131  * if signaled, check the SDS values within a range
132  */
133  if (cur_sds.flg_rng == 1) {
134  /*
135  * read the SDS
136  */
137  tot_pts = 1;
138  for (i = 0; i < a_rank; i++) {
139  start[i] = 0;
140  tot_pts *= a_range[i];
141  }
142  ptr = (void *) malloc(tot_pts * cur_sds.byt_per_val);
143 
144  if (SDreaddata(sds_id, start, NULL, a_range, ptr) < 0) {
145  printf("**** SDS: '%s', SDreaddata failed reading %d values\n",
146  cur_sds.name, tot_pts);
147  fmt_status = fmt_status | 2;
148  } else {
149  /*
150  * for each type that is processed, check each value within the min
151  * / max range or is not a number (not finite for doubles)
152  */
153  icount = 0;
154  irem = -1;
155  switch (a_type) {
156  case DFNT_FLOAT32:
157  sprintf(range_str, "%f and %f", cur_sds.sds_rng.f32[0],
158  cur_sds.sds_rng.f32[1]);
159  ptr_f32 = (float32 *) ptr;
160 
161  s_range.f32[0] = *ptr_f32;
162  s_range.f32[1] = *ptr_f32;
163 
164  for (i = 0; i < tot_pts; i++) {
165  if (*(ptr_f32 + i) < s_range.f32[0])
166  s_range.f32[0] = *(ptr_f32 + i);
167  if (*(ptr_f32 + i) > s_range.f32[1])
168  s_range.f32[1] = *(ptr_f32 + i);
169 
170  if (*(ptr_f32 + i) < cur_sds.sds_rng.f32[0] ||
171  *(ptr_f32 + i) > cur_sds.sds_rng.f32[1] ||
172  isnan(*(ptr_f32 + i))) {
173  irem = (irem < 0) ? i : irem; /* remember first occurence */
174  icount++; /* and total # of occurences */
175  }
176  }
177  sprintf(s_range_str, "%f to %f", s_range.f32[0], s_range.f32[1]);
178  break;
179  case DFNT_FLOAT64:
180  sprintf(range_str, "%f and %f", cur_sds.sds_rng.f64[0],
181  cur_sds.sds_rng.f64[1]);
182  ptr_f64 = (float64 *) ptr;
183 
184  s_range.f64[0] = *ptr_f64;
185  s_range.f64[1] = *ptr_f64;
186 
187  for (i = 0; i < tot_pts; i++) {
188  if (*(ptr_f64 + i) < s_range.f64[0])
189  s_range.f64[0] = *(ptr_f64 + i);
190  if (*(ptr_f64 + i) > s_range.f64[1])
191  s_range.f64[1] = *(ptr_f64 + i);
192 
193  if (*(ptr_f64 + i) < cur_sds.sds_rng.f64[0] ||
194  *(ptr_f64 + i) > cur_sds.sds_rng.f64[1] ||
195  !isfinite(*(ptr_f64 + i))) {
196  irem = (irem < 0) ? i : irem; /* remember first occurence */
197  icount++;
198  /* and total # of occurences */ }
199  }
200  sprintf(s_range_str, "%f to %f", s_range.f64[0], s_range.f64[1]);
201  break;
202  case DFNT_INT32:
203  sprintf(range_str, "%d and %d", cur_sds.sds_rng.i32[0],
204  cur_sds.sds_rng.i32[1]);
205  ptr_i32 = (int32 *) ptr;
206 
207  s_range.i32[0] = *ptr_i32;
208  s_range.i32[1] = *ptr_i32;
209 
210  for (i = 0; i < tot_pts; i++) {
211  if (*(ptr_i32 + i) < s_range.i32[0])
212  s_range.i32[0] = *(ptr_i32 + i);
213  if (*(ptr_i32 + i) > s_range.i32[1])
214  s_range.i32[1] = *(ptr_i32 + i);
215 
216  if (*(ptr_i32 + i) < cur_sds.sds_rng.i32[0] ||
217  *(ptr_i32 + i) > cur_sds.sds_rng.i32[1]) {
218  irem = (irem < 0) ? i : irem; /* remember first occurence */
219  icount++;
220  /* and total # of occurences */ }
221  }
222  sprintf(s_range_str, "%d to %d", s_range.i32[0], s_range.i32[1]);
223  break;
224  case DFNT_INT16:
225  sprintf(range_str, "%d and %d", cur_sds.sds_rng.i16[0],
226  cur_sds.sds_rng.i16[1]);
227  ptr_i16 = (int16 *) ptr;
228 
229  s_range.i16[0] = *ptr_i16;
230  s_range.i16[1] = *ptr_i16;
231 
232  for (i = 0; i < tot_pts; i++) {
233  if (*(ptr_i16 + i) < s_range.i16[0])
234  s_range.i16[0] = *(ptr_i16 + i);
235  if (*(ptr_i16 + i) > s_range.i16[1])
236  s_range.i16[1] = *(ptr_i16 + i);
237 
238  if (*(ptr_i16 + i) < cur_sds.sds_rng.i16[0] ||
239  *(ptr_i16 + i) > cur_sds.sds_rng.i16[1]) {
240  irem = (irem < 0) ? i : irem; /* remember first occurence */
241  icount++;
242  /* and total # of occurences */ }
243  }
244  sprintf(s_range_str, "%d to %d", s_range.i16[0], s_range.i16[1]);
245  break;
246  case DFNT_INT8:
247  sprintf(range_str, "%d and %d", cur_sds.sds_rng.i8[0],
248  cur_sds.sds_rng.i8[1]);
249  ptr_i8 = (int8 *) ptr;
250 
251  s_range.i8[0] = *ptr_i8;
252  s_range.i8[1] = *ptr_i8;
253 
254  for (i = 0; i < tot_pts; i++) {
255  if (*(ptr_i8 + i) < s_range.i8[0])
256  s_range.i8[0] = *(ptr_i8 + i);
257  if (*(ptr_i8 + i) > s_range.i8[1])
258  s_range.i8[1] = *(ptr_i8 + i);
259 
260  if (*(ptr_i8 + i) < cur_sds.sds_rng.i8[0] ||
261  *(ptr_i8 + i) > cur_sds.sds_rng.i8[1]) {
262  irem = (irem < 0) ? i : irem; /* remember first occurence */
263  icount++;
264  /* and total # of occurences */ }
265  }
266  sprintf(s_range_str, "%d to %d", s_range.i8[0], s_range.i8[1]);
267  break;
268  case DFNT_UINT8:
269  sprintf(range_str, "%d and %d", cur_sds.sds_rng.ui8[0],
270  cur_sds.sds_rng.ui8[1]);
271  ptr_ui8 = (uint8 *) ptr;
272 
273  s_range.ui8[0] = *ptr_ui8;
274  s_range.ui8[1] = *ptr_ui8;
275 
276  for (i = 0; i < tot_pts; i++) {
277 
278  if (*(ptr_ui8 + i) < s_range.ui8[0])
279  s_range.ui8[0] = *(ptr_ui8 + i);
280  if (*(ptr_ui8 + i) > s_range.ui8[1])
281  s_range.ui8[1] = *(ptr_ui8 + i);
282 
283  if (*(ptr_ui8 + i) < cur_sds.sds_rng.ui8[0] ||
284  *(ptr_ui8 + i) > cur_sds.sds_rng.ui8[1]) {
285  irem = (irem < 0) ? i : irem; /* remember first occurence */
286  icount++;
287  /* and total # of occurences */ }
288  }
289  sprintf(s_range_str, "%d to %d", s_range.ui8[0], s_range.ui8[1]);
290  break;
291  }
292  /*
293  * report any problem sdses Also, print dimension in '[]'
294  */
295  if (icount > 0) {
296  printf("**** SDS: '%s', has a value outside valid range of %s.\n",
297  cur_sds.name, range_str);
298  printf(" (or is not a number)\n");
299  printf(" first point at linear loc. %d, # invalid: %d, dims: [",
300  irem, icount);
301  for (i = 0; i < a_rank; i++)
302  printf(" %d ", a_range[i]);
303  printf("]\n");
304  fmt_status = fmt_status | 2;
305  }
306 
307  /*
308  * report sds range if desired
309  */
310  if (verbose == 1) {
311  printf("sds: '%s' has a min max range of: %s\n", cur_sds.name,
312  s_range_str);
313  }
314  }
315  free(ptr);
316  } else {
317  if (verbose == 1) {
318  printf("sds: '%s' was checked\n", cur_sds.name);
319  }
320  }
321  /*
322  * Now, check the attributes for this sds
323  */
324  if (cur_sds.n_attr > 0) {
325  for (i = 0; i < cur_sds.n_attr; i++) {
326  ind = cur_sds.attr_ind[i];
327  if (get_attr(sds_id, fmt->att[ ind ], &value, &a_count)
328  == 0) {
329  /*
330  * code to print attribute info
331  */
332  attr_disp(fmt->att[ ind ], value, a_count);
333  }
334  }
335  }
336  return 0;
337 }
an array had not been initialized Several spelling and grammar corrections were which is read from the appropriate MCF the above metadata values were hard coded A problem calculating the average background DN for SWIR bands when the moon is in the space view port was corrected The new algorithm used to calculate the average background DN for all reflective bands when the moon is in the space view port is now the same as the algorithm employed by the thermal bands For non SWIR changes in the averages are typically less than Also for non SWIR the black body DNs remain a backup in case the SV DNs are not available For SWIR the changes in computed averages were larger because the old which used the black body suffered from contamination by the micron leak As a consequence of the if SV DNs are not available for the SWIR the EV pixels will not be the granule time is used to identify the appropriate tables within the set given for one LUT the first two or last two tables respectively will be used for the interpolation If there is only one LUT in the set of it will be treated as a constant LUT The manner in which Earth View data is checked for saturation was changed Previously the raw Earth View DNs and Space View DNs were checked against the lookup table values contained in the table dn_sat The change made is to check the raw Earth and Space View DNs to be sure they are less than the maximum saturation value and to check the Space View subtracted Earth View dns against a set of values contained in the new lookup table dn_sat_ev The metadata configuration and ASSOCIATEDINSTRUMENTSHORTNAME from the MOD02HKM product The same metatdata with extensions and were removed from the MOD021KM and MOD02OBC products ASSOCIATEDSENSORSHORTNAME was set to MODIS in all products These changes are reflected in new File Specification which users may consult for exact the pow functions were eliminated in Emissive_Cal and Emissive bands replaced by more efficient code Other calculations throughout the code were also made more efficient Aside from a few round off there was no difference to the product The CPU time decreased by about for a day case and for a night case A minor bug in calculating the uncertainty index for emissive bands was corrected The frame index(0-based) was previously being used the frame number(1-based) should have been used. There were only a few minor changes to the uncertainty index(maximum of 1 digit). 3. Some inefficient arrays(Sigma_RVS_norm_sq) were eliminated and some code lines in Preprocess_L1A_Data were moved into Process_OBCEng_Emiss. There were no changes to the product. Required RAM was reduced by 20 MB. Now
integer, parameter int16
Definition: cubeio.f90:3
int32 value
Definition: Granule.c:1235
#define NULL
Definition: decode_rs.h:63
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_INT32
int chk_sds(int32 fid, fmt_str *fmt, int isds)
Definition: chk_sds.c:11
int fmt_status
Definition: fmt_check.c:7
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_INT16
int verbose
Definition: fmt_check.c:6
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_FLOAT32
int get_attr(int32, attr_str, u_data *, int *)
Definition: get_attr.c:10
int i
Definition: decode_rs.h:71
void attr_disp(attr_str attr, u_data value, int a_count)
Definition: attr_disp.c:5