OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
hdf4_utils.c
Go to the documentation of this file.
1 #include "hdf4utils.h"
2 
3 #include <hdf.h>
4 #include <mfhdf.h>
5 
6 /*----------------------------------------------------------------------------*/
7 
8 int load_att(int32_t obj_id, int32_t index, att_struct *att) {
9  int32_t status = FAIL;
10 
11  /* initialize */
12  att->data = NULL;
13  att->id = obj_id;
14  att->index = index;
15  status = SDattrinfo(att->id,
16  att->index,
17  att->name,
18  &att->ntype,
19  &att->nvals);
20  if (status) return status;
21 
22  /* read data */
23  if (att->nvals > 0) {
24  att->data = malloc(att->nvals * DFKNTsize(att->ntype));
25  status = SDreadattr(att->id, att->index, att->data);
26  }
27 
28  return status;
29 }
30 
31 int load_att_byname(int32_t obj_id, const char *attname, att_struct *att) {
32  int32_t status;
33  status = load_att(obj_id, SDfindattr(obj_id, attname), att);
34  return status;
35 }
36 
37 void print_att_info(const att_struct att) {
38  if (att.data) {
39  printf("%8s", "");
40  //printf("%2d ",att.index);
41  printf("%-22s ", att.name);
42  printf("%10s [%d]", hdf_typename(att.ntype), att.nvals);
43  if (att.nvals == 1)
44  printf(" = %s", fmt_hdf_val(att.data, 0, att.ntype));
45  //printf("data = %p",att.data);
46  printf("\n");
47  }
48 }
49 
50 void print_att_vals(const att_struct att) {
51  int32_t i;
52  printf("%-22s = ", att.name);
53  if (att.data) {
54 
55  /* string */
56  if (att.ntype == DFNT_CHAR8)
57  printf("\"%s\"", (char *) att.data);
58 
59  /* scalar number */
60  else
61  if (att.nvals == 1)
62  printf("%s", fmt_hdf_val(att.data, 0, att.ntype));
63 
64  /* array of numbers */
65  else {
66  printf("[");
67  for (i = 0; i < att.nvals; i++) {
68  printf("%s", fmt_hdf_val(att.data, i, att.ntype));
69  printf("%s", (i < att.nvals - 1) ? ", " : "]");
70  }
71  }
72  printf("\n");
73  }
74 }
75 
76 int init_attlist(sds_struct *sds) {
77  int32_t i;
78  int32_t status = FAIL;
79 
80  /* allocate array to hold all attribute info */
81  sds->atts = malloc(sds->natts * sizeof (att_struct));
82 
83  /* load attribute info */
84  for (i = 0; i < sds->natts; i++)
85  status = load_att(sds->id, i, &sds->atts[i]);
86 
87  return status;
88 }
89 
90 /*----------------------------------------------------------------------------*/
91 
92 int init_sds_byname(int32_t fileid, const char *sdsname, sds_struct *sds) {
93  int32_t status = FAIL;
94  strcpy(sds->name, sdsname);
95  sds->data = NULL;
96  sds->id = SDselect(fileid, SDnametoindex(fileid, sdsname));
97  status = SDgetinfo(sds->id, NULL,
98  &sds->ndims, sds->dimlen,
99  &sds->ntype, &sds->natts);
100  return status;
101 }
102 
103 void print_sds_info(const sds_struct s) {
104  int32_t i;
105  printf("%4s", "");
106  //printf("%8d",s.id);
107  printf("%-22s", s.name);
108  if (s.id != FAIL) {
109  printf("%10s [", hdf_typename(s.ntype));
110  for (i = 0; i < s.ndims; i++) {
111  printf("%d", s.dimlen[i]);
112  printf("%s", i < s.ndims - 1 ? "," : "]");
113  }
114  //printf("%2d attributes.", s.natts);
115  }
116  printf("\n");
117 }
118 
119 int init_sdslist(int32_t fileid, const char *sdsnames[], sds_struct *sdslist) {
120  int32_t n_sds, i = 0;
121 
122  /* allocate array to hold all SDS info */
123  while (sdsnames[i]) i++;
124  n_sds = i;
125  sdslist = malloc(n_sds * sizeof (sds_struct));
126 
127  /* load SDS info */
128  for (i = 0; i < n_sds; i++)
129  init_sds_byname(fileid, sdsnames[i], &sdslist[i]);
130 
131  /* print SDS info */
132  for (i = 0; i < n_sds; i++)
134 
135  return n_sds;
136 }
137 
138 int readall_sds(sds_struct *sds) {
139  int32_t i;
140  int32_t status = FAIL;
141  int32_t *start, *edges;
142  if (sds->id != FAIL) {
143  start = malloc(sds->ndims * sizeof (int32_t));
144  edges = malloc(sds->ndims * sizeof (int32_t));
145  sds->nvals = 1;
146  for (i = 0; i < sds->ndims; i++) {
147  start[i] = 0;
148  edges[i] = sds->dimlen[i];
149  sds->nvals *= sds->dimlen[i];
150  }
151  sds->data = malloc(sds->nvals * DFKNTsize(sds->ntype));
152  status = SDreaddata(sds->id, start, NULL, edges, sds->data);
153  free(start);
154  free(edges);
155  }
156  return status;
157 }
158 
159 /*----------------------------------------------------------------------------*/
160 
161 void free_sds(sds_struct *sds) {
162  int32_t i;
163 
164  /* Free space allocated for SDS data */
165  if (sds->data) {
166  free(sds->data);
167  sds->data = NULL;
168  }
169 
170  /* Free space allocated for each populated SDS attribute*/
171  if (sds->atts) {
172  for (i = 0; i < sds->natts; i++)
173  if (sds->atts[i].data) {
174  free(sds->atts[i].data);
175  sds->atts[i].data = NULL;
176  }
177  free(sds->atts);
178  sds->atts = NULL;
179  }
180 
181  /* Terminate access to the data set */
182  SDendaccess(sds->id);
183  sds->id = FAIL;
184 
185 }
186 
187 /*----------------------------------------------------------------------------*/
188 
189 const char *hdf_typename(const int32_t ntype) {
190  /* Named initializers automatically size the array as needed */
191  static const char* typenames[] = {
192  [DFNT_UCHAR8] = "uchar8",
193  [DFNT_CHAR8] = "char8",
194  [DFNT_FLOAT32] = "float32",
195  [DFNT_FLOAT64] = "float64",
196  [DFNT_INT8] = "int8",
197  [DFNT_UINT8] = "uint8",
198  [DFNT_INT16] = "int16",
199  [DFNT_UINT16] = "uint16",
200  [DFNT_INT32] = "int32",
201  [DFNT_UINT32] = "uint32",
202  [DFNT_INT64] = "int64",
203  [DFNT_UINT64] = "uint64"
204  };
205  static const int32_t maxindex = sizeof (typenames) / sizeof (typenames[0]);
206  if ((ntype < 0) || (maxindex <= ntype))
207  return "unknown";
208  return typenames[ntype];
209 }
210 
211 char *fmt_hdf_val(const void *array, const int32_t i, const int32_t ntype) {
212  char *val = NULL;
213  val = malloc(40 * sizeof (char));
214  memset(val, '\0', 40);
215 
216  if (array)
217  switch (ntype) {
218  case DFNT_UCHAR8: /* == 3 */
219  sprintf(val, "%d", ((uchar8 *) array)[i]);
220  break;
221  case DFNT_CHAR8: /* == 4 */
222  sprintf(val, "%c", ((char8 *) array)[i]);
223  break;
224  case DFNT_FLOAT32: /* == 5 */
225  sprintf(val, "%f", ((float *) array)[i]);
226  break;
227  case DFNT_FLOAT64: /* == 6 */
228  sprintf(val, "%f", ((double *) array)[i]);
229  break;
230  case DFNT_INT8: /* == 20 */
231  sprintf(val, "%d", ((int8_t *) array)[i]);
232  break;
233  case DFNT_UINT8: /* == 21 */
234  sprintf(val, "%u", ((uint8_t *) array)[i]);
235  break;
236  case DFNT_INT16: /* == 22 */
237  sprintf(val, "%d", ((int16_t *) array)[i]);
238  break;
239  case DFNT_UINT16: /* == 23 */
240  sprintf(val, "%u", ((uint16_t *) array)[i]);
241  break;
242  case DFNT_INT32: /* == 24 */
243  sprintf(val, "%ld", (long) ((int32_t *) array)[i]);
244  break;
245  case DFNT_UINT32: /* == 25 */
246  sprintf(val, "%lu", (unsigned long) ((uint32_t *) array)[i]);
247  break;
248  case DFNT_INT64: /* == 26 */
249  sprintf(val, "%lld", ((long long *) array)[i]);
250  break;
251  case DFNT_UINT64: /* == 27 */
252  sprintf(val, "%llu", ((unsigned long long *) array)[i]);
253  break;
254  default:
255  fprintf(stderr, "Unknown type code: %d\n", ntype);
256  break;
257  } /* end switch */
258  return (val);
259 }
260 
261 void fopen_warn(const char *filename, const char *file, const int32_t line) {
262  fprintf(stderr, "-W- %s:%d: Cannot open file: %s\n",
263  file, line, filename);
264 }
265 
266 void fopen_err(const char *filename, const char *file, const int32_t line) {
267  fprintf(stderr, "-E- %s:%d: Cannot open file: %s\n",
268  file, line, filename);
269  exit(1);
270 }
271 
272 /*----------------------------------------------------------------------------*/
273 
274 int parse_odl(const char *odltext, const char *object, char *value) {
275  char *p = NULL; /* pointer to current character */
276  char *q = NULL; /* pointer to end of list */
277  char endstring[4] = ""; /* marks end of list */
278 
279  /* advance pointer to first instance of specified string */
280  /* (will trip on ambiguous text) */
281  if ((p = strstr(odltext, object)) == NULL)
282  return 0;
283 
284  /* advance pointer to next instance of "VALUE" */
285  if ((p = strstr(p, "VALUE")) == NULL)
286  return 0;
287 
288  /* advance pointer past next instance of "=" */
289  if ((p = strstr(p, "=")) == NULL)
290  return 0;
291  p++;
292 
293  /* advance pointer to next non-blank character */
294  while (*p == ' ') p++;
295 
296  /* if it's an open paren, look for close paren to end value list */
297  /* - otherwise use newline. */
298  strcpy(endstring, (*p == '(') ? ")" : "\n");
299 
300  /* find end of value list */
301  if ((q = strstr(p, endstring)) == NULL)
302  return 0;
303 
304  /* advance pointer to next character not in [("] */
305  while ((*p == '(') || (*p == '"')) p++;
306 
307  /* copy each remaining character not in [")] */
308  /* put on a single line */
309  while ((*p) && (p < q)) {
310  if ((*p != '"') && (*p != '\n')) {
311  *value = *p;
312  value++;
313  }
314  if (*p == ' ') {
315  while (*p == ' ') p++;
316  }/* skip multiple blanks */
317  else p++;
318  }
319 
320  /* terminate the string */
321  *value = 0;
322 
323  return strlen(value);
324 }
325 
326 int get_hdfeos_meta(int32_t sd_id, char *attribute, char *name, char *data) {
327  char eosmeta[EOSMETALEN] = "";
328  if (SDreadattr(sd_id, SDfindattr(sd_id, attribute), (VOIDP) eosmeta) != 0) {
329  printf("Error reading attribute %s\n", attribute);
330  return -1;
331  }
332  return (parse_odl(eosmeta, name, data) == 0) ? -1 : 0;
333 }
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
data_t q
Definition: decode_rs.h:74
int32 value
Definition: Granule.c:1235
int load_att(int32_t obj_id, int32_t index, att_struct *att)
Definition: hdf4_utils.c:8
char * fmt_hdf_val(const void *array, const int32_t i, const int32_t ntype)
Definition: hdf4_utils.c:211
int status
Definition: l1_czcs_hdf.c:32
const char * hdf_typename(const int32_t ntype)
Definition: hdf4_utils.c:189
#define FAIL
Definition: ObpgReadGrid.h:18
#define NULL
Definition: decode_rs.h:63
void print_att_vals(const att_struct att)
Definition: hdf4_utils.c:50
int init_sds_byname(int32_t fileid, const char *sdsname, sds_struct *sds)
Definition: hdf4_utils.c:92
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_INT32
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude resolving resolving GSFcd00179 Corrected handling of fill values for[Sensor|Solar][Zenith|Azimuth] resolving MODxl01751 Changed to validate LUT version against a value retrieved from the resolving MODxl02056 Changed to calculate Solar Diffuser angles without adjustment for estimated post launch changes in the MODIS orientation relative to incidentally resolving defects MODxl01766 Also resolves MODxl01947 Changed to ignore fill values in SCI_ABNORM and SCI_STATE rather than treating them as resolving MODxl01780 Changed to use spacecraft ancillary data to recognise when the mirror encoder data is being set by side A or side B and to change calculations accordingly This removes the need for seperate LUTs for Side A and Side B data it makes the new LUTs incompatible with older versions of the and vice versa Also resolves MODxl01685 A more robust GRing algorithm is being which will create a non default GRing anytime there s even a single geolocated pixel in a granule Removed obsolete messages from seed file
Definition: HISTORY.txt:413
char filename[FILENAME_MAX]
Definition: atrem_corl1.h:122
int parse_odl(const char *odltext, const char *object, char *value)
Definition: hdf4_utils.c:274
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_INT16
int get_hdfeos_meta(int32_t sd_id, char *attribute, char *name, char *data)
Definition: hdf4_utils.c:326
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude data
Definition: HISTORY.txt:356
void print_sds_info(const sds_struct s)
Definition: hdf4_utils.c:103
void fopen_warn(const char *filename, const char *file, const int32_t line)
Definition: hdf4_utils.c:261
void free_sds(sds_struct *sds)
Definition: hdf4_utils.c:161
int readall_sds(sds_struct *sds)
Definition: hdf4_utils.c:138
data_t s[NROOTS]
Definition: decode_rs.h:75
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_FLOAT32
void fopen_err(const char *filename, const char *file, const int32_t line)
Definition: hdf4_utils.c:266
int i
Definition: decode_rs.h:71
msiBandIdx val
Definition: l1c_msi.cpp:34
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
int load_att_byname(int32_t obj_id, const char *attname, att_struct *att)
Definition: hdf4_utils.c:31
int init_sdslist(int32_t fileid, const char *sdsnames[], sds_struct *sdslist)
Definition: hdf4_utils.c:119
#define EOSMETALEN
Definition: filetype.c:23
float p[MODELMAX]
Definition: atrem_corl1.h:131
int init_attlist(sds_struct *sds)
Definition: hdf4_utils.c:76
void print_att_info(const att_struct att)
Definition: hdf4_utils.c:37