Due to the lapse in federal government funding, NASA is not updating this website. We sincerely regret this inconvenience.
NASA Logo
Ocean Color Science Software

ocssw V2022
hdf5util.cpp
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <time.h>
4 #include <string.h>
5 #include <math.h>
6 
7 #include "hdf5utils.h"
8 #include "passthebuck.h"
9 
10 #define FAIL -1
11 
12 #define DATACENTER "NASA/GSFC Aquarius Data Processing Center"
13 #define MISSIONCHARACTERISTICS "Nominal orbit: inclination=98.0 (Sun-synchronous); node=6PM (ascending); eccentricity=<0.002; altitude=657 km; ground speed=6.825 km/sec"
14 
15 #define SENSORCHARACTERISTICS "Number of beams=3; channels per receiver=4; frequency 1.413 GHz; bits per sample=16; instatntaneous field of view=6.5 degrees; science data block period=1.44 sec."
16 
17 // Millisecs since start of day
18 
19 int32_t get_millisec(string *ydhmsf_str) {
20  istringstream istr;
21  int32_t itemp;
22 
23  istr.clear();
24  istr.str(ydhmsf_str->substr(7, 2));
25  istr >> itemp;
26  int32_t millisec = itemp * 3600000;
27  istr.clear();
28  istr.str(ydhmsf_str->substr(9, 2));
29  istr >> itemp;
30  millisec += itemp * 60000;
31  istr.clear();
32  istr.str(ydhmsf_str->substr(11, 5));
33  istr >> itemp;
34  millisec += itemp;
35 
36  return millisec;
37 }
38 
39 namespace Hdf {
40 
41 int h5a_set(hid_t dataset, const char *nam, hid_t typ,
42  hid_t cnt, void* data) {
43 
44  hid_t attr, atype, wr_typ, aid;
45  hsize_t fdim[1];
46 
47  /* Save old error handler */
48  H5E_auto_t old_func;
49  void *old_client_data;
50  H5Eget_auto(H5E_DEFAULT, &old_func, &old_client_data);
51 
52  /* Turn off error handling */
53  H5Eset_auto(H5E_DEFAULT, NULL, NULL);
54 
55  /* Probe. Likely to fail, but that's okay */
56  attr = H5Aopen_name(dataset, nam);
57 
58  /* Restore previous error handler */
59  H5Eset_auto(H5E_DEFAULT, old_func, old_client_data);
60 
61  // Write attribute if it exists and return
62  if (attr > 0) {
63  if (H5Awrite(attr, typ, data)) {
64  fprintf(stderr, "-E- %s line %d: ", __FILE__, __LINE__);
65  fprintf(stderr, "H5Awrite(%ld,\"%s\",%ld,%ld,data) failed. ",
66  (long) dataset, nam, (long) typ, (long) cnt);
67  return (HDF_FUNCTION_ERROR);
68  }
69  H5Aclose(attr);
70  return (LIFE_IS_GOOD);
71  }
72 
73 
74  if (typ == H5T_STRING) {
75  /*
76  * Create string attribute.
77  */
78  aid = H5Screate(H5S_SCALAR);
79 
80  atype = H5Tcopy(H5T_C_S1);
81  H5Tset_size(atype, cnt);
82 
83  attr = H5Acreate1(dataset, nam, atype, aid, H5P_DEFAULT);
84  wr_typ = atype;
85 
86  } else if (cnt == 1) {
87  /*
88  * Create scalar attribute.
89  */
90  aid = H5Screate(H5S_SCALAR);
91  attr = H5Acreate1(dataset, nam, typ, aid, H5P_DEFAULT);
92  wr_typ = typ;
93 
94  } else {
95  aid = H5Screate(H5S_SIMPLE);
96  fdim[0] = cnt;
97  H5Sset_extent_simple(aid, 1, fdim, NULL);
98 
99  /*
100  * Create array attribute.
101  */
102  attr = H5Acreate1(dataset, nam, typ, aid, H5P_DEFAULT);
103  wr_typ = typ;
104  }
105 
106  /*
107  * Write attribute.
108  */
109  if (H5Awrite(attr, wr_typ, data)) {
110  fprintf(stderr, "-E- %s line %d: ", __FILE__, __LINE__);
111  fprintf(stderr, "H5Awrite(%ld,\"%s\",%ld,%ld,data) failed. ",
112  (long) dataset, nam, (long) typ, (long) cnt);
113  return (HDF_FUNCTION_ERROR);
114  }
115 
116  /*
117  * Close attribute and file dataspaces.
118  */
119  H5Sclose(aid);
120 
121  /*
122  * Close the attributes.
123  */
124  H5Aclose(attr);
125 
126  return (LIFE_IS_GOOD);
127 }
128 
129 hid_t h5d_create(hid_t grp, const char *nam, hid_t typ,
130  int rank,
131  hsize_t d0, hsize_t d1, hsize_t d2,
132  hsize_t d3, hsize_t d4, hsize_t d5,
133  hid_t *dataset,
134  hid_t *dataspace,
135  hid_t plist) {
136 
137  hsize_t dimsizes[6];
138 
139  if (rank > 6) {
140  fprintf(stderr, "-E- %s line %d: ", __FILE__, __LINE__);
141  fprintf(stderr, "sd_create() expects to be passed a rank <= 6. ");
142  return (PROGRAMMER_BOOBOO);
143  }
144  dimsizes[0] = d0;
145  dimsizes[1] = d1;
146  dimsizes[2] = d2;
147  dimsizes[3] = d3;
148  dimsizes[4] = d4;
149  dimsizes[5] = d5;
150 
151  *dataspace = H5Screate(H5S_SIMPLE);
152  H5Sset_extent_simple(*dataspace, rank, dimsizes, NULL);
153 
154  if ((*dataset = H5Dcreate1(grp, nam, typ,
155  *dataspace, plist)) == FAIL) {
156  fprintf(stderr, "-E- %s line %d: ", __FILE__, __LINE__);
157  fprintf(stderr, "H5Dcreate(%ld,\"%s\",%ld,%ld,[%ld,%ld,%ld]) failed. ",
158  (long) grp, nam, (long) typ, (long) rank,
159  (long) d0, (long) d1, (long) d2);
160  return (HDF_FUNCTION_ERROR);
161  }
162 
163  return (LIFE_IS_GOOD);
164 }
165 
166 int SetScalarH5A(hid_t id, const char *name, hid_t type, const void *value) {
167  if (type == H5T_STRING)
168  h5a_set(id, name, type, strlen((char *) value) + 1, (void*) value);
169  else
170  h5a_set(id, name, type, 1, (void*) value);
171 
172  return (LIFE_IS_GOOD);
173 }
174 
175 
176 
177 /* ----------------------------------------------------- */
178 /* Create an H5D using the wrappers for the HDF routines */
179 
180 /* ----------------------------------------------------- */
182  hid_t grp, /* group id */
183  const char *sname, /* short name */
184  const char *lname, /* long name */
185  const char *units, /* units (not set if passed NULL or "") */
186  double low, /* low end of valid range */
187  double high, /* high end of range (no range set if low >= high) */
188  float slope, /* scale factor (not set if 0) */
189  float offset, /* scaling offset (not set if 0) */
190  hid_t nt, /* HDF number type */
191  int rank, /* number of dimensions (must be <= 3) */
192  int32_t d0, /* size of 1st dimension */
193  int32_t d1, /* size of 2nd dimension */
194  int32_t d2, /* size of 3rd dimension */
195  int32_t d3, /* size of 4th dimension */
196  int32_t d4, /* size of 5th dimension */
197  int32_t d5, /* size of 6th dimension */
198  const char *dn0, /* name of 1st dimension */
199  const char *dn1, /* name of 2nd dimension */
200  const char *dn2, /* name of 3rd dimension */
201  const char *dn3, /* name of 4th dimension */
202  const char *dn4, /* name of 5th dimension */
203  const char *dn5, /* name of 6th dimension */
204  hid_t plist /* Dataset property list */
205  ) {
206 
207  hid_t dataset, dataspace;
208 
209  /* Create the SDS */
210  PTB(h5d_create(grp, sname, nt, rank, d0, d1, d2, d3, d4, d5,
211  &dataset, &dataspace, plist));
212 
213  /* Add a "long_name" attribute */
214  PTB(SetScalarH5A(dataset, "long_name", (hid_t) H5T_STRING, lname));
215  /* Add a "valid_range" attribute if one is specified */
216  if (nt == H5T_NATIVE_UCHAR) {
217  unsigned char vr[2];
218  vr[0] = (unsigned char) low;
219  vr[1] = (unsigned char) high;
220  PTB(h5a_set(dataset, "valid_min", H5T_NATIVE_UCHAR, 1, (void*) & vr[0]));
221  PTB(h5a_set(dataset, "valid_max", H5T_NATIVE_UCHAR, 1, (void*) & vr[1]));
222  } else if (nt == H5T_NATIVE_USHORT) {
223  short vr[2];
224  vr[0] = (short) low;
225  vr[1] = (short) high;
226  PTB(h5a_set(dataset, "valid_min", H5T_NATIVE_USHORT, 1, (void*) & vr[0]));
227  PTB(h5a_set(dataset, "valid_max", H5T_NATIVE_USHORT, 1, (void*) & vr[1]));
228  } else if (nt == H5T_STD_I32LE) {
229  int32_t vr[2];
230  vr[0] = (int32_t) low;
231  vr[1] = (int32_t) high;
232  PTB(h5a_set(dataset, "valid_min", H5T_STD_I32LE, 1, (void*) & vr[0]));
233  PTB(h5a_set(dataset, "valid_max", H5T_STD_I32LE, 1, (void*) & vr[1]));
234  } else if (nt == H5T_STD_U32LE) {
235  int32_t vr[2];
236  vr[0] = (int32_t) low;
237  vr[1] = (int32_t) high;
238  PTB(h5a_set(dataset, "valid_min", H5T_STD_U32LE, 1, (void*) & vr[0]));
239  PTB(h5a_set(dataset, "valid_max", H5T_STD_U32LE, 1, (void*) & vr[1]));
240  } else if (nt == H5T_NATIVE_FLOAT) {
241  float vr[2];
242  vr[0] = (float) low;
243  vr[1] = (float) high;
244  PTB(h5a_set(dataset, "valid_min", H5T_NATIVE_FLOAT, 1, (void*) & vr[0]));
245  PTB(h5a_set(dataset, "valid_max", H5T_NATIVE_FLOAT, 1, (void*) & vr[1]));
246  } else if (nt == H5T_NATIVE_DOUBLE) {
247  double vr[2];
248  vr[0] = (float) low;
249  vr[1] = (float) high;
250  PTB(h5a_set(dataset, "valid_min", H5T_NATIVE_DOUBLE, 1, (void*) & vr[0]));
251  PTB(h5a_set(dataset, "valid_max", H5T_NATIVE_DOUBLE, 1, (void*) & vr[1]));
252  } else {
253  fprintf(stderr, "-E- %s line %d: ", __FILE__, __LINE__);
254  fprintf(stderr, "Got unsupported number type (%ld) ", (long) nt);
255  fprintf(stderr, "while trying to create SDS, \"%s\", ", sname);
256  exit(1);
257  }
258 
259 
260  /* Add a "slope" attribute if one is specified, and also
261  an intercept attribute */
262  if (slope != 0) {
263  PTB(h5a_set(dataset, "slope", H5T_NATIVE_FLOAT, 1, (void*) & slope));
264  }
265  if (offset != 0) {
266  PTB(h5a_set(dataset, "intercept", H5T_NATIVE_FLOAT, 1, (void*) & offset));
267  }
268 
269  /* Add a "units" attribute if one is specified */
270  if (units != NULL && *units != 0) {
271  PTB(SetScalarH5A(dataset, "units", (hid_t) H5T_STRING, units));
272  }
273 
274 
275  /* Release this SDS */
276  PTB(H5Sclose(dataspace));
277  PTB(H5Dclose(dataset));
278 
279  return (LIFE_IS_GOOD);
280 }
281 
282 
283 
284 /* ----------------------------------------------------- */
285 /* Create an H5D using the wrappers for the HDF routines */
286 
287 /* ----------------------------------------------------- */
289  hid_t grp, /* group id */
290  const char *sname, /* short name */
291  const char *lname, /* long name */
292  const char *stdname, /* standard name */
293  const char *units, /* units (not set if passed NULL or "") */
294  double low, /* low end of valid range */
295  double high, /* high end of range (no range set if low >= high) */
296  float slope, /* scale factor (not set if 0) */
297  float offset, /* scaling offset (not set if 0) */
298  float fillvalue, /* fill value */
299  hid_t nt, /* HDF number type */
300  int rank, /* number of dimensions (must be <= 3) */
301  int32_t d0, /* size of 1st dimension */
302  int32_t d1, /* size of 2nd dimension */
303  int32_t d2, /* size of 3rd dimension */
304  int32_t d3, /* size of 4th dimension */
305  int32_t d4, /* size of 5th dimension */
306  int32_t d5, /* size of 6th dimension */
307  const char *dn0, /* name of 1st dimension */
308  const char *dn1, /* name of 2nd dimension */
309  const char *dn2, /* name of 3rd dimension */
310  const char *dn3, /* name of 4th dimension */
311  const char *dn4, /* name of 5th dimension */
312  const char *dn5, /* name of 6th dimension */
313  hid_t plist /* Dataset property list */
314  ) {
315 
316  hid_t dataset;
317 
318  CreateH5D(grp, sname, lname, units, low, high, slope, offset,
319  nt, rank, d0, d1, d2, d3, d4, d5,
320  dn0, dn1, dn2, dn3, dn4, dn5, plist);
321 
322  dataset = H5Dopen1(grp, sname);
323 
324  if (nt == H5T_NATIVE_SHORT) {
325  short _FillValue;
326  _FillValue = (short) fillvalue;
327  PTB(h5a_set(dataset, "_FillValue", H5T_NATIVE_SHORT, 1, (void*) & _FillValue));
328  } else if (nt == H5T_STD_I32LE) {
329  int32_t _FillValue;
330  _FillValue = (int32_t) fillvalue;
331  PTB(h5a_set(dataset, "_FillValue", H5T_STD_I32LE, 1, (void*) & _FillValue));
332  } else if (nt == H5T_NATIVE_FLOAT) {
333  float _FillValue;
334  _FillValue = (float) fillvalue;
335  PTB(h5a_set(dataset, "_FillValue", H5T_NATIVE_FLOAT, 1, (void*) & _FillValue));
336  } else if (nt == H5T_NATIVE_DOUBLE) {
337  double _FillValue;
338  _FillValue = (float) fillvalue;
339  PTB(h5a_set(dataset, "_FillValue", H5T_NATIVE_DOUBLE, 1, (void*) & _FillValue));
340  } else {
341  fprintf(stderr, "-E- %s line %d: ", __FILE__, __LINE__);
342  fprintf(stderr, "Got unsupported number type (%ld) ", (long) nt);
343  fprintf(stderr, "while trying to create SDS, \"%s\", ", sname);
344  return (PROGRAMMER_BOOBOO);
345  }
346 
347 
348  // Standard Name
349  if (strlen(stdname) != 0) {
350  PTB(SetScalarH5A(dataset, "standard_name", (hid_t) H5T_STRING, stdname));
351  }
352 
353  /* Release this SDS */
354  PTB(H5Dclose(dataset));
355 
356  return (LIFE_IS_GOOD);
357 }
358 
359 
360 
361 /*---------------------- */
362 /* Write to HDF5 dataset */
363 
364 /* --------------------- */
365 herr_t h5d_write(hid_t id, const char *name, void* data, hsize_t rank,
366  hsize_t s[6], hsize_t e[6]) {
367 
368  hid_t dataset, dataspace, filespace, datatype;
369  hsize_t start[6], edge[6], dims[6];
370 
371  for (size_t i = 0; i < 6; i++) {
372  start[i] = s[i];
373  edge[i] = e[i];
374  }
375 
376 
377  dataset = H5Dopen1(id, name);
378  if (dataset == -1) {
379  printf("Dataset: %s not found (%d)\n", name, (int)id);
380  exit(1);
381  }
382 
383  /* Get datatype */
384  /* ------------ */
385  datatype = H5Dget_type(dataset);
386 
387  /*
388  * Select a hyperslab.
389  */
390  filespace = H5Dget_space(dataset);
391 
392 
393  // Check for out-of-bounds write
394  H5Sget_simple_extent_dims(filespace, dims, NULL);
395  for (size_t i = 0; i < rank; i++) {
396  if (start[i] + edge[i] > dims[i]) {
397  printf("Write to dim (0-based): %d of \"%s\" out of bounds (%d %d)\n",
398  (int) i, name, (int) (start[i] + edge[i]), (int) dims[i]);
399  exit(110);
400  }
401  }
402 
403  H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start, NULL,
404  edge, NULL);
405 
406  dataspace = H5Screate_simple(rank, edge, NULL);
407 
408  /*
409  * Write the data to the hyperslab.
410  */
411  H5Dwrite(dataset, datatype, dataspace, filespace,
412  H5P_DEFAULT, data);
413 
414  H5Dclose(dataset);
415  H5Sclose(dataspace);
416  H5Sclose(filespace);
417 
418  return (LIFE_IS_GOOD);
419 }
420 
421 
422 
423 /*----------------------- */
424 /* Read from HDF5 dataset */
425 
426 /* ---------------------- */
427 herr_t h5d_read(hid_t id, const char *name, void* data, hsize_t rank,
428  hsize_t s[6], hsize_t e[6]) {
429 
430  hid_t dataset, dataspace, filespace, datatype;
431  hsize_t start[6], edge[6], dims[6];
432 
433  dataset = H5Dopen1(id, name);
434  if (dataset == -1) {
435  printf("Dataset: %s not found (%d)\n", name, (int)id);
436  exit(1);
437  }
438 
439  // Get datatype
440  datatype = H5Dget_type(dataset);
441 
442  // Select hyperslab
443  filespace = H5Dget_space(dataset);
444 
445  // Return dimensions if data = NULL
446  if (data == NULL) {
447  for (size_t i = 0; i < 6; i++) e[i] = 0;
448  H5Sget_simple_extent_dims(filespace, e, NULL);
449  H5Dclose(dataset);
450  H5Sclose(filespace);
451  return (LIFE_IS_GOOD);
452  }
453 
454  // Copy start and edge
455  for (size_t i = 0; i < 6; i++) {
456  start[i] = s[i];
457  edge[i] = e[i];
458  }
459 
460  // Check for out-of-bounds read
461  H5Sget_simple_extent_dims(filespace, dims, NULL);
462  for (size_t i = 0; i < rank; i++) {
463  if (start[i] + edge[i] > dims[i]) {
464  printf("Read to dim (0-based): %d of \"%s\" out of bounds (%d %d)\n",
465  (int) i, name, (int) (start[i] + edge[i]), (int) dims[i]);
466  exit(110);
467  }
468  }
469 
470  H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start, NULL,
471  edge, NULL);
472 
473  dataspace = H5Screate_simple(rank, edge, NULL);
474 
475  /*
476  * Read the data from the hyperslab.
477  */
478  H5Dread(dataset, datatype, dataspace, filespace,
479  H5P_DEFAULT, data);
480 
481  H5Dclose(dataset);
482  H5Sclose(dataspace);
483  H5Sclose(filespace);
484  H5Tclose(datatype);
485 
486  return (LIFE_IS_GOOD);
487 }
488 
489 } // namespace Hdf
int32 value
Definition: Granule.c:1235
Definition: bin_io.cpp:23
#define NULL
Definition: decode_rs.h:63
hid_t h5d_create(hid_t grp, const char *nam, hid_t typ, int rank, hsize_t d0, hsize_t d1, hsize_t d2, hsize_t d3, hsize_t d4, hsize_t d5, hid_t *dataset, hid_t *dataspace, hid_t plist)
Definition: hdf5util.cpp:129
#define LIFE_IS_GOOD
Definition: passthebuck.h:4
#define FAIL
Definition: hdf5util.cpp:10
float32 slope[]
Definition: l2lists.h:30
int32_t get_millisec(string *ydhmsf_str)
Definition: hdf5util.cpp:19
but the philosophy of the MODIS L1 routines is that the output granule must be if it contains even a single packet of useable data Some of the spacecraft ancillary data in L0 datasets is available only on a cycle that repeates every seconds MOD_PR01 therefore looks backwards up to for such packets If the seconds preceeding the start of an MOD_PR01 run are covered by a different L0 dataset
Definition: MOD_PR01_pr.txt:33
#define PTB(function)
Definition: passthebuck.h:16
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude data
Definition: HISTORY.txt:356
Extra metadata that will be written to the HDF4 file l2prod rank
herr_t h5d_write(hid_t id, const char *name, void *data, hsize_t rank, hsize_t s[6], hsize_t e[6])
Definition: hdf5util.cpp:365
data_t s[NROOTS]
Definition: decode_rs.h:75
l2prod offset
herr_t h5d_read(hid_t id, const char *name, void *data, hsize_t rank, hsize_t s[6], hsize_t e[6])
Definition: hdf5util.cpp:427
int CreateH5D(hid_t grp, const char *sname, const char *lname, const char *units, double low, double high, float slope, float offset, hid_t nt, int rank, int32_t d0, int32_t d1, int32_t d2, int32_t d3, int32_t d4, int32_t d5, const char *dn0, const char *dn1, const char *dn2, const char *dn3, const char *dn4, const char *dn5, hid_t plist)
Definition: hdf5util.cpp:181
int i
Definition: decode_rs.h:71
int SetScalarH5A(hid_t id, const char *name, hid_t type, const void *value)
Definition: hdf5util.cpp:166
#define PROGRAMMER_BOOBOO
Definition: passthebuck.h:8
#define HDF_FUNCTION_ERROR
Definition: passthebuck.h:7
int h5a_set(hid_t dataset, const char *nam, hid_t typ, hid_t cnt, void *data)
Definition: hdf5util.cpp:41