OB.DAAC Logo
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