1/* This is part of the netCDF package.
2   Copyright 2005 University Corporation for Atmospheric Research/Unidata
3   See COPYRIGHT file for conditions of use.
4
5   Test HDF5 file code. These are not intended to be exhaustive tests,
6   but they use HDF5 the same way that netCDF-4 does, so if these
7   tests don't work, than netCDF-4 won't work either.
8
9   $Id: tst_h_dimscales.c,v 1.15 2010/06/01 15:34:51 ed Exp $
10*/
11#include "h5_err_macros.h"
12#include <hdf5.h>
13#include <H5DSpublic.h>
14
15#define FILE_NAME "tst_h_dimscales.h5"
16#define STR_LEN 255
17#define MAX_DIMS 255
18
19herr_t alien_visitor(hid_t did, unsigned dimhid_t dsid,
20      void *visitor_data)
21{
22   char name1[STR_LEN], name2[STR_LEN];
23   H5G_stat_t statbuf;
24
25   (*(hid_t *)visitor_data) = dsid;
26   if (H5Iget_name(didname1STR_LEN) < 0) ERR;
27   if (H5Iget_name(dsidname2STR_LEN) < 0) ERR;
28/*    printf("visiting did 0x%x dim %d dsid 0x%x name of did %s \n",  */
29/*    did, dim, dsid, name1); */
30/*    printf("name of dsid: %s\n", name2); */
31
32   if (H5Gget_objinfo(did, ".", 1, &statbuf) < 0) ERR;
33/*   printf("statbuf.fileno = %d statbuf.objno = %d\n",
34     statbuf.fileno, statbuf.objno);*/
35
36   return 0;
37}
38
39int
40rec_scan_group(hid_t grpid)
41{
42   hid_t spaceiddatasetid = 0, child_grpid;
43   hsize_t num_obji;
44   int obj_class;
45   char obj_name[STR_LEN + 1];
46   htri_t is_scale;
47   int num_scales;
48   hsize_t dims[MAX_DIMS], max_dims[MAX_DIMS];
49   int ndimsd;
50
51   /* Loop through datasets to find variables. */
52   if (H5Gget_num_objs(grpid, &num_obj) < 0) ERR;
53   for (i=0; i<num_obji++)
54   {
55      /* Get the type (i.e. group, dataset, etc.), and the name of
56       * the object. */
57      if ((obj_class = H5Gget_objtype_by_idx(grpidi)) < 0) ERR;
58      if (H5Gget_objname_by_idx(grpidiobj_nameSTR_LEN) < 0) ERR;
59      /*printf("\nEncountered: HDF5 object obj_class %d obj_name %s\n",
60 obj_class, obj_name);*/
61
62      /* Deal with groups and datasets, ignore the rest. */
63      switch(obj_class)
64      {
65  case H5G_GROUP:
66     if ((child_grpid = H5Gopen(grpidobj_name)) < 0) ERR;
67     if (rec_scan_group(child_grpid)) ERR;
68     break;
69  case H5G_DATASET:
70     /* Open the dataset. */
71     if ((datasetid = H5Dopen(grpidobj_name)) < 0) ERR;
72     /*printf("\nobj_name %s\n", obj_name);*/
73
74     /* Get the dimensions of this dataset. */
75     if ((spaceid = H5Dget_space(datasetid)) < 0) ERR;
76     if ((ndims = H5Sget_simple_extent_ndims(spaceid)) < 0) ERR;
77     if (ndims > MAX_DIMSERR;
78     if (H5Sget_simple_extent_dims(spaceiddimsmax_dims) < 0) ERR;
79
80     /* Is this a dimscale? */
81     if ((is_scale = H5DSis_scale(datasetid)) < 0) ERR;
82     if (is_scale)
83     {
84        /*printf("dimension scale! Hoorah for the Pirate King!\n");*/
85     }
86     else
87     {
88        int visitor_data = 0;
89
90        /* Here's how to get the number of scales attached
91 * to the dataset's dimension 0. */
92        if ((num_scales = H5DSget_num_scales(datasetid, 0)) < 0) ERR;
93        if (num_scales != 1) ERR;
94
95        /* Go through all dimscales for this var and learn about them. */
96        for (d = 0; d < ndimsd++)
97   if (H5DSiterate_scales(datasetiddNULLalien_visitor,
98  &visitor_data) < 0) ERR;
99     }
100     if (H5Dclose(datasetid) < 0) ERR;
101     break;
102  case H5G_TYPE:
103     printf("found a type!\n");
104     break;
105  case H5G_LINK:
106     printf("found a link! Yikes!\n");
107     break;
108  default:
109     printf("Unknown object class %d!", obj_class);
110      }
111   }
112
113   return 0;
114}
115
116int
117main()
118{
119   printf("\n*** Checking HDF5 dimension scales.\n");
120#define GRP_NAME "simple_scales"
121#define DIMSCALE_NAME "dimscale"
122#define NAME_ATTRIBUTE "Billy-Bob"
123#define VAR1_NAME "var1"
124#define VAR2_NAME "var2"
125#define VAR3_NAME "var3"
126#define DIM1_LEN 3
127#define DIM2_LEN 2
128#define FIFTIES_SONG "Mamma said they'll be days like this. They'll be days like this, my mamma said."
129
130   printf("*** Creating simple dimension scales file...");
131   {
132      hid_t fileidgrpiddimscaleid;
133      hid_t dimscale_spaceidvar1_spaceidvar3_spaceid;
134      hid_t var1_datasetidvar2_datasetidvar3_datasetid;
135      hsize_t dims[2] = {DIM1_LENDIM2_LEN};
136      hsize_t dimscale_dims[1] = {DIM1_LEN};
137
138      /* Open file and create group. */
139      if ((fileid = H5Fcreate(FILE_NAMEH5F_ACC_TRUNCH5P_DEFAULT,
140       H5P_DEFAULT)) < 0) ERR;
141      if ((grpid = H5Gcreate(fileidGRP_NAME, 0)) < 0) ERR;
142
143      /* Create our dimension scale. Use the built-in NAME attribute
144       * on the dimscale. */
145      if ((dimscale_spaceid = H5Screate_simple(1, dimscale_dims,
146        dimscale_dims)) < 0) ERR;
147      if ((dimscaleid = H5Dcreate(grpidDIMSCALE_NAMEH5T_NATIVE_INT,
148   dimscale_spaceidH5P_DEFAULT)) < 0) ERR;
149      if (H5DSset_scale(dimscaleidNAME_ATTRIBUTE) < 0) ERR;
150
151      /* Create a 1D variable which uses the dimscale. Attach a label
152       * to this scale. */
153      if ((var1_spaceid = H5Screate_simple(1, dimsdims)) < 0) ERR;
154      if ((var1_datasetid = H5Dcreate(grpidVAR1_NAMEH5T_NATIVE_INT,
155       var1_spaceidH5P_DEFAULT)) < 0) ERR;
156      if (H5DSattach_scale(var1_datasetiddimscaleid, 0) < 0) ERR;
157      if (H5DSset_label(var1_datasetid, 0, FIFTIES_SONG) < 0) ERR;
158
159      /* Create a 1D variabls that doesn't use the dimension scale. */
160      if ((var2_datasetid = H5Dcreate(grpidVAR2_NAMEH5T_NATIVE_INT,
161       var1_spaceidH5P_DEFAULT)) < 0) ERR;
162
163      /* Create a 2D dataset which uses the scale for one of its
164       * dimensions. */
165      if ((var3_spaceid = H5Screate_simple(2, dimsdims)) < 0) ERR;
166      if ((var3_datasetid = H5Dcreate(grpidVAR3_NAMEH5T_NATIVE_INT,
167       var3_spaceidH5P_DEFAULT)) < 0) ERR;
168      if (H5DSattach_scale(var3_datasetiddimscaleid, 0) < 0) ERR;
169
170      /* Close up the shop. */
171      if (H5Dclose(dimscaleid) < 0 ||
172   H5Dclose(var1_datasetid) < 0 ||
173   H5Dclose(var2_datasetid) < 0 ||
174   H5Dclose(var3_datasetid) < 0 ||
175   H5Sclose(var1_spaceid) < 0 ||
176   H5Sclose(var3_spaceid) < 0 ||
177   H5Sclose(dimscale_spaceid) < 0 ||
178   H5Gclose(grpid) < 0 ||
179   H5Fclose(fileid) < 0) ERR;
180
181      /* HELP! If you are reading this in the future, and time
182       * machines have been invented, please come back to July 10,
183       * 2005, the Java Java coffee shop in Lafayette, 8:00 am MST +-
184       * 20 minutes. Bring back some advanced weapons systems to
185       * destroy the sound system here, which is playing 50's rock and
186       * roll. Do-op, do-op, la-ma la-ma, ding dong. Save me!!! (Mind
187       * you, James Brown is a different story!) */
188   }
189   SUMMARIZE_ERR;
190   printf("*** Checking that simple dimscale file can be read...");
191   {
192      hid_t fileidgrpiddatasetid = 0;
193      hsize_t num_obji;
194      int obj_class;
195      char obj_name[STR_LEN + 1];
196      htri_t is_scale;
197      int num_scales;
198
199      /* Reopen the file and group. */
200      if ((fileid = H5Fopen(FILE_NAMEH5F_ACC_RDWRH5P_DEFAULT)) < 0) ERR;
201      if ((grpid = H5Gopen(fileidGRP_NAME)) < 0) ERR;
202
203      /* Loop through datasets to find variables. */
204      if (H5Gget_num_objs(grpid, &num_obj) < 0) ERR;
205      for (i=0; i<num_obji++)
206      {
207  /* Get the type (i.e. group, dataset, etc.), and the name of the
208   * object. Confusingly, this is a different type than the type
209   * of a variable. This type might be better called "class" or
210   * "type of type"  */
211  if ((obj_class = H5Gget_objtype_by_idx(grpidi)) < 0) ERR;
212  if (H5Gget_objname_by_idx(grpidiobj_nameSTR_LEN) < 0) ERR;
213  /*printf("\nEncountered: HDF5 object obj_class %d obj_name %s\n", obj_class, obj_name);*/
214
215  /* Deal with groups and datasets. */
216  switch(obj_class)
217  {
218     case H5G_GROUP:
219        break;
220     case H5G_DATASET:
221
222        /*Close the last datasetid, if one is open. */
223        if (datasetid > 0)
224        {
225   H5Dclose(datasetid);
226        }
227
228        if ((datasetid = H5Dopen(grpidobj_name)) < 0) ERR;
229        if ((is_scale = H5DSis_scale(datasetid)) < 0) ERR;
230        if (is_scale && strcmp(obj_nameDIMSCALE_NAME)) ERR;
231        if (is_scale)
232        {
233   char nom_de_quincey[STR_LEN+1];
234
235   /* A dimscale comes with a NAME attribute, in
236    * addition to its real name. */
237   if (H5DSget_scale_name(datasetidnom_de_quincey,
238  STR_LEN) < 0) ERR;
239   if (strcmp(nom_de_quinceyNAME_ATTRIBUTE)) ERR;
240
241   /*printf("found scale %s, NAME %s\n", obj_name, nom_de_quincey);*/
242
243        }
244        else
245        {
246   char label[STR_LEN+1];
247
248   /* Here's how to get the number of scales attached
249    * to the dataset. I would think that this would
250    * return 0 scales for a dataset that doesn't have
251    * scales, but instead it errors. So take an error
252    * to be the same as no dimension scales. */
253   num_scales = H5DSget_num_scales(datasetid, 0);
254   if (strcmp(obj_nameVAR1_NAME) == 0 && num_scales != 1) ERR;
255   if (strcmp(obj_nameVAR2_NAME) == 0 && num_scales > 0) ERR;
256   if (strcmp(obj_nameVAR3_NAME) == 0 && num_scales != 1) ERR;
257
258   /* There's also a label for dimension 0 of var1. */
259   if (strcmp(obj_nameVAR1_NAME) == 0)
260   {
261      if (H5DSget_label(datasetid, 0, labelSTR_LEN) < 0) ERR;
262      if (strcmp(labelFIFTIES_SONG)) ERR;
263   }
264        }
265        break;
266     case H5G_TYPE:
267        break;
268     case H5G_LINK:
269        break;
270     default:
271        printf("Unknown object class %d!", obj_class);
272  }
273      }
274
275      /* Close up the shop. */
276      if (H5Dclose(datasetid) < 0 ||
277   H5Gclose(grpid) < 0 ||
278   H5Fclose(fileid) < 0) ERR;
279   }
280
281   SUMMARIZE_ERR;
282   printf("*** Creating simple dimension scales file with lots of datasets...");
283
284#define NUM_DATASETS 500
285   {
286      hid_t fileidgrpiddimscaleid;
287      hid_t dimscale_spaceidvar1_spaceid;
288      hid_t var1_datasetid[NUM_DATASETS];
289      hsize_t dims[2] = {DIM1_LENDIM2_LEN};
290      hsize_t dimscale_dims[1] = {DIM1_LEN};
291      char var_name[STR_LEN + 1];
292      int v;
293
294      /* Open file and create group. */
295      if ((fileid = H5Fcreate(FILE_NAMEH5F_ACC_TRUNCH5P_DEFAULT,
296       H5P_DEFAULT)) < 0) ERR;
297      if ((grpid = H5Gcreate(fileidGRP_NAME, 0)) < 0) ERR;
298
299      /* Create our dimension scale. Use the built-in NAME attribute
300       * on the dimscale. */
301      if ((dimscale_spaceid = H5Screate_simple(1, dimscale_dims,
302        dimscale_dims)) < 0) ERR;
303      if ((dimscaleid = H5Dcreate(grpidDIMSCALE_NAMEH5T_NATIVE_INT,
304   dimscale_spaceidH5P_DEFAULT)) < 0) ERR;
305      if (H5DSset_scale(dimscaleidNAME_ATTRIBUTE) < 0) ERR;
306
307      /* Create many 1D datasets which use the dimscale. */
308      if ((var1_spaceid = H5Screate_simple(1, dimsdims)) < 0) ERR;
309      for (v = 0; v < NUM_DATASETSv++)
310      {
311  sprintf(var_name, "var_%d", v);
312  if ((var1_datasetid[v] = H5Dcreate(grpidvar_nameH5T_NATIVE_INT,
313     var1_spaceidH5P_DEFAULT)) < 0) ERR;
314  if (H5DSattach_scale(var1_datasetid[v], dimscaleid, 0) < 0) ERR;
315      }
316
317      /* Close up the shop. */
318      for (v = 0; v < NUM_DATASETSv++)
319  if (H5Dclose(var1_datasetid[v]) < 0) ERR;
320      if (H5Dclose(dimscaleid) < 0 ||
321   H5Sclose(var1_spaceid) < 0 ||
322   H5Sclose(dimscale_spaceid) < 0 ||
323   H5Gclose(grpid) < 0 ||
324   H5Fclose(fileid) < 0) ERR;
325   }
326
327   SUMMARIZE_ERR;
328   printf("*** Creating a file with an unlimited dimension scale...");
329
330   {
331      hid_t fileidgrpidspaceiddatasetiddimscaleidcparmsid;
332      hsize_t dims[1] = {1}, maxdims[1] = {H5S_UNLIMITED};
333
334      /* Create file and group. */
335      if ((fileid = H5Fcreate(FILE_NAMEH5F_ACC_TRUNCH5P_DEFAULT,
336       H5P_DEFAULT)) < 0) ERR;
337      if ((grpid = H5Gcreate(fileidGRP_NAME, 0)) < 0) ERR;
338
339      if ((spaceid = H5Screate_simple(1, dimsmaxdims)) < 0) ERR;
340
341      /* Modify dataset creation properties, i.e. enable chunking  */
342      if ((cparmsid = H5Pcreate(H5P_DATASET_CREATE)) < 0) ERR;
343      if (H5Pset_chunk(cparmsid, 1, dims) < 0) ERR;
344
345      /* Create our dimension scale, as an unlimited dataset. */
346      if ((dimscaleid = H5Dcreate(grpidDIMSCALE_NAMEH5T_NATIVE_INT,
347   spaceidcparmsid)) < 0) ERR;
348      if (H5DSset_scale(dimscaleidNAME_ATTRIBUTE) < 0) ERR;
349
350      /* Create a variable which uses it. */
351      if ((datasetid = H5Dcreate(grpidVAR1_NAMEH5T_NATIVE_INT,
352  spaceidcparmsid)) < 0) ERR;
353      if (H5DSattach_scale(datasetiddimscaleid, 0) < 0) ERR;
354      if (H5DSset_label(datasetid, 0, "dimension label") < 0) ERR;
355
356      /* Close up the shop. */
357      if (H5Dclose(dimscaleid) < 0 ||
358   H5Dclose(datasetid) < 0 ||
359   H5Sclose(spaceid) < 0 ||
360   H5Gclose(grpid) < 0 ||
361   H5Fclose(fileid) < 0) ERR;
362   }
363
364   SUMMARIZE_ERR;
365#ifdef EXTRA_TESTS
366   printf("*** Checking that unlimited dimscale file can be read...");
367
368   {
369      hid_t fileidgrpidspaceid = 0, datasetid = 0;
370      hsize_t num_obji;
371      int obj_class;
372      char obj_name[STR_LEN + 1];
373      htri_t is_scale;
374      int num_scales;
375      hsize_t dims[1], maxdims[1];
376
377      /* Reopen the file and group. */
378      if ((fileid = H5Fopen(FILE_NAMEH5F_ACC_RDWRH5P_DEFAULT)) < 0) ERR;
379      if ((grpid = H5Gopen(fileidGRP_NAME)) < 0) ERR;
380
381      /* Loop through datasets to find variables. */
382      if (H5Gget_num_objs(grpid, &num_obj) < 0) ERR;
383      for (i=0; i<num_obji++)
384      {
385  /* Get the type (i.e. group, dataset, etc.), and the name of
386   * the object. */
387  if ((obj_class = H5Gget_objtype_by_idx(grpidi)) < 0) ERR;
388  if (H5Gget_objname_by_idx(grpidiobj_nameSTR_LEN) < 0) ERR;
389  /*printf("\nEncountered: HDF5 object obj_class %d obj_name %s\n", obj_class, obj_name);*/
390
391  /* Deal with groups and datasets. */
392  switch(obj_class)
393  {
394     case H5G_GROUP:
395        break;
396     case H5G_DATASET:
397
398        /*Close the last datasetid, if one is open. */
399        if (datasetid > 0)
400        {
401   H5Dclose(datasetid);
402   datasetid = 0;
403        }
404
405        /* Open the dataset. */
406        if ((datasetid = H5Dopen(grpidobj_name)) < 0) ERR;
407
408        /* This should be an unlimited dataset. */
409        if ((spaceid = H5Dget_space(datasetid)) < 0) ERR;
410        if (H5Sget_simple_extent_dims(spaceiddimsmaxdims) < 0) ERR;
411        if (maxdims[0] != H5S_UNLIMITEDERR;
412
413        /* Is this a dimscale? */
414        if ((is_scale = H5DSis_scale(datasetid)) < 0) ERR;
415        if (is_scale && strcmp(obj_nameDIMSCALE_NAME)) ERR;
416        if (is_scale)
417        {
418   char nom_de_quincey[STR_LEN+1];
419
420   /* A dimscale comes with a NAME attribute, in
421    * addition to its real name. */
422   if (H5DSget_scale_name(datasetidnom_de_quinceySTR_LEN) < 0) ERR;
423   /*printf("found scale %s, NAME %s\n", obj_name, nom_de_quincey);*/
424
425        }
426        else
427        {
428   char label[STR_LEN+1];
429   int visitor_data = 0;
430
431   /* Here's how to get the number of scales attached
432    * to the dataset's dimension 0. */
433   if ((num_scales = H5DSget_num_scales(datasetid, 0)) < 0) ERR;
434   if (num_scales != 1) ERR;
435
436   /* Go through all dimscales for this var and learn about them. */
437   if (H5DSiterate_scales(datasetid, 0, NULLalien_visitor,
438  &visitor_data) < 0) ERR;
439
440   /* There's also a label for dimension 0. */
441   if (H5DSget_label(datasetid, 0, labelSTR_LEN) < 0) ERR;
442
443   /*printf("found non-scale dataset %s, label %s\n", obj_name, label);*/
444        }
445        break;
446     case H5G_TYPE:
447        break;
448     case H5G_LINK:
449        break;
450     default:
451        printf("Unknown object class %d!", obj_class);
452  }
453      }
454
455      /* Close up the shop. */
456      if (H5Dclose(datasetid) < 0 ||
457   H5Sclose(spaceid) < 0 ||
458   H5Gclose(grpid) < 0 ||
459   H5Fclose(fileid) < 0) ERR;
460   }
461
462   SUMMARIZE_ERR;
463   printf("*** Creating some 3D datasets using shared dimscales...");
464
465   {
466#define NDIMS 3
467#define TIME_DIM 0
468#define LAT_DIM 1
469#define LON_DIM 2
470#define LAT_LEN 2
471#define LON_LEN 3
472#define LAT_NAME "Lat"
473#define LON_NAME "Lon"
474#define TIME_NAME "Time"
475#define PRES_NAME "Pressure"
476#define TEMP_NAME "Temperature"
477
478      hid_t fileidgrpidlat_spaceidlon_spaceidtime_spaceidspaceid;
479      hid_t lat_scaleidlon_scaleidtime_scaleid;
480      hid_t pres_dsidtemp_dsidcparmsid;
481      hsize_t dims[NDIMS], max_dims[NDIMS];
482
483      /* Create file and group. */
484      if ((fileid = H5Fcreate(FILE_NAMEH5F_ACC_TRUNCH5P_DEFAULT,
485       H5P_DEFAULT)) < 0) ERR;
486      if ((grpid = H5Gcreate(fileidGRP_NAME, 0)) < 0) ERR;
487
488      /* Create 3 1D spaces for the 3 dimension scale datasets. Time
489       * starts out as size 0. It's an unlimited dimension scale. */
490      dims[0] = 0;
491      max_dims[0] = H5S_UNLIMITED;
492      if ((time_spaceid = H5Screate_simple(1, dimsmax_dims)) < 0) ERR;
493      dims[0] = LAT_LEN;
494      max_dims[0] = LAT_LEN;
495      if ((lat_spaceid = H5Screate_simple(1, dimsmax_dims)) < 0) ERR;
496      dims[0] = LON_LEN;
497      max_dims[0] = LON_LEN;
498      if ((lon_spaceid = H5Screate_simple(1, dimsmax_dims)) < 0) ERR;
499
500      /* Enable chunking for unlimited time scale.  */
501      if ((cparmsid = H5Pcreate(H5P_DATASET_CREATE)) < 0) ERR;
502      dims[TIME_DIM] = 1;
503      if (H5Pset_chunk(cparmsid, 1, dims) < 0) ERR;
504
505      /* Create our dimension scales. */
506      if ((time_scaleid = H5Dcreate(grpidTIME_NAMEH5T_NATIVE_INT,
507     time_spaceidcparmsid)) < 0) ERR;
508      if (H5DSset_scale(time_scaleidTIME_NAME) < 0) ERR;
509      if ((lat_scaleid = H5Dcreate(grpidLAT_NAMEH5T_NATIVE_FLOAT,
510    lat_spaceidH5P_DEFAULT)) < 0) ERR;
511      if (H5DSset_scale(lat_scaleidLAT_NAME) < 0) ERR;
512      if ((lon_scaleid = H5Dcreate(grpidLON_NAMEH5T_NATIVE_FLOAT,
513    lon_spaceidH5P_DEFAULT)) < 0) ERR;
514      if (H5DSset_scale(lon_scaleidLON_NAME) < 0) ERR;
515
516      /* Create a space coresponding to these three dimensions. */
517      dims[TIME_DIM] = 0;
518      dims[LAT_DIM] = LAT_LEN;
519      dims[LON_DIM] = LON_LEN;
520      max_dims[TIME_DIM] = H5S_UNLIMITED;
521      max_dims[LAT_DIM] = LAT_LEN;
522      max_dims[LON_DIM] = LON_LEN;
523      if ((spaceid = H5Screate_simple(NDIMSdimsmax_dims)) < 0) ERR;
524
525      /* Create two variables which use them, and attach the dimension scales. */
526      dims[TIME_DIM] = 1;
527      if (H5Pset_chunk(cparmsidNDIMSdims) < 0) ERR;
528      if ((pres_dsid = H5Dcreate(grpidPRES_NAMEH5T_NATIVE_FLOAT,
529  spaceidcparmsid)) < 0) ERR;
530      if (H5DSattach_scale(pres_dsidtime_scaleid, 0) < 0) ERR;
531      if (H5DSattach_scale(pres_dsidlat_scaleid, 1) < 0) ERR;
532      if (H5DSattach_scale(pres_dsidlon_scaleid, 2) < 0) ERR;
533      if (H5DSset_label(pres_dsidTIME_DIMTIME_NAME) < 0) ERR;
534      if (H5DSset_label(pres_dsidLAT_DIMLAT_NAME) < 0) ERR;
535      if (H5DSset_label(pres_dsidLON_DIMLON_NAME) < 0) ERR;
536      if ((temp_dsid = H5Dcreate(grpidTEMP_NAMEH5T_NATIVE_FLOAT,
537  spaceidcparmsid)) < 0) ERR;
538      if (H5DSattach_scale(temp_dsidtime_scaleid, 0) < 0) ERR;
539      if (H5DSattach_scale(temp_dsidlat_scaleid, 1) < 0) ERR;
540      if (H5DSattach_scale(temp_dsidlon_scaleid, 2) < 0) ERR;
541      if (H5DSset_label(temp_dsidTIME_DIMTIME_NAME) < 0) ERR;
542      if (H5DSset_label(temp_dsidLAT_DIMLAT_NAME) < 0) ERR;
543      if (H5DSset_label(temp_dsidLON_DIMLON_NAME) < 0) ERR;
544
545      /* Close up the shop. */
546      if (H5Dclose(pres_dsid) < 0 ||
547   H5Dclose(temp_dsid) < 0 ||
548   H5Dclose(lat_scaleid) < 0 ||
549   H5Dclose(lon_scaleid) < 0 ||
550   H5Dclose(time_scaleid) < 0 ||
551   H5Sclose(spaceid) < 0 ||
552   H5Gclose(grpid) < 0 ||
553   H5Fclose(fileid) < 0) ERR;
554   }
555
556   SUMMARIZE_ERR;
557   printf("*** Checking 3D datasets created with shared dimscales...");
558
559   {
560      hid_t fileidgrpidspaceid = 0, datasetid = 0;
561      hsize_t num_obji;
562      int obj_class;
563      char obj_name[STR_LEN + 1];
564      htri_t is_scale;
565      int num_scales;
566      hsize_t dims[NDIMS], max_dims[NDIMS];
567      int d;
568
569      /* Reopen the file and group. */
570      if ((fileid = H5Fopen(FILE_NAMEH5F_ACC_RDWRH5P_DEFAULT)) < 0) ERR;
571      if ((grpid = H5Gopen(fileidGRP_NAME)) < 0) ERR;
572
573      /* Loop through datasets to find variables. */
574      if (H5Gget_num_objs(grpid, &num_obj) < 0) ERR;
575      for (i=0; i<num_obji++)
576      {
577  /* Get the type (i.e. group, dataset, etc.), and the name of
578   * the object. */
579  if ((obj_class = H5Gget_objtype_by_idx(grpidi)) < 0) ERR;
580  if (H5Gget_objname_by_idx(grpidiobj_nameSTR_LEN) < 0) ERR;
581  /*printf("\nEncountered: HDF5 object obj_class %d obj_name %s\n", obj_class, obj_name);*/
582
583  /* Deal with groups and datasets. */
584  switch(obj_class)
585  {
586     case H5G_GROUP:
587        break;
588     case H5G_DATASET:
589        /* Open the dataset. */
590        if ((datasetid = H5Dopen(grpidobj_name)) < 0) ERR;
591        /*printf("\nobj_name %s\n", obj_name);*/
592
593        /* Get the dimensions of this dataset. */
594        if ((spaceid = H5Dget_space(datasetid)) < 0) ERR;
595        if (H5Sget_simple_extent_dims(spaceiddimsmax_dims) < 0) ERR;
596
597        /* Is this a dimscale? */
598        if ((is_scale = H5DSis_scale(datasetid)) < 0) ERR;
599        if (is_scale)
600        {
601   char nom_de_quincey[STR_LEN+1];
602
603   /* A dimscale comes with a NAME attribute, in
604    * addition to its real name. */
605   if (H5DSget_scale_name(datasetidnom_de_quincey,
606  STR_LEN) < 0) ERR;
607   /*printf("found scale %s, NAME %s id 0x%x\n", obj_name,
608     nom_de_quincey, datasetid);*/
609
610   /* Check size depending on name. */
611   if ((!strcmp(obj_nameLAT_NAME) && dims[TIME_DIM] != LAT_LEN) ||
612       (!strcmp(obj_nameLON_NAME) && dims[TIME_DIM] != LON_LEN) ||
613       (!strcmp(obj_nameTIME_NAME) &&
614        max_dims[TIME_DIM] != H5S_UNLIMITED)) ERR;
615
616        }
617        else
618        {
619   char label[STR_LEN+1];
620   int visitor_data = 0;
621
622   /* SHould have these dimensions... */
623   if (dims[TIME_DIM] != 0 || dims[LAT_DIM] != LAT_LEN ||
624       dims[LON_DIM] != LON_LENERR;
625   if (max_dims[TIME_DIM] != H5S_UNLIMITEDERR;
626
627   /* Here's how to get the number of scales attached
628    * to the dataset's dimension 0. */
629   if ((num_scales = H5DSget_num_scales(datasetid, 0)) < 0) ERR;
630   if (num_scales != 1) ERR;
631
632   /* Go through all dimscales for this var and learn
633    * about them. What I want is the dataset id of each
634    * dimscale. Then... */
635   for (d = 0; d < NDIMSd++)
636      if (H5DSiterate_scales(datasetiddNULLalien_visitor,
637     &visitor_data) < 0) ERR;
638   /*printf("visitor_data: 0x%x\n", visitor_data);*/
639
640   /* There's also a label for each dimension. */
641   if (H5DSget_label(datasetid, 0, labelSTR_LEN) < 0) ERR;
642   if (strcmp(labelTIME_NAME)) ERR;
643   if (H5DSget_label(datasetid, 1, labelSTR_LEN) < 0) ERR;
644   if (strcmp(labelLAT_NAME)) ERR;
645   if (H5DSget_label(datasetid, 2, labelSTR_LEN) < 0) ERR;
646   if (strcmp(labelLON_NAME)) ERR;
647        }
648        if (H5Dclose(datasetid) < 0) ERR;
649        break;
650     case H5G_TYPE:
651        break;
652     case H5G_LINK:
653        break;
654     default:
655        printf("Unknown object class %d!", obj_class);
656  }
657      }
658
659      /* Close up the shop. */
660      if (H5Sclose(spaceid) < 0 ||
661   H5Gclose(grpid) < 0 ||
662   H5Fclose(fileid) < 0) ERR;
663   }
664
665   SUMMARIZE_ERR;
666   printf("*** Creating 3D datasets using shared dimscales in groups...");
667
668   {
669#define FATHER "Adam"
670#define GOOD_CHILD "Able"
671#define BAD_CHILD "Cain"
672#define DISTANCE_LEN 3
673#define SMELLINESS_NAME "Smelliness"
674#define DISTANCE_NAME "Distance"
675#define TIME_NAME "Time"
676#define TIME_DIM 0
677#define SMELLINESS_DIM 1
678#define DISTANCE_DIM 2
679#define GOAT_NAME "Billy_goat_gruff"
680#define CAMEL_NAME "Grumpy_the_camel"
681
682      hid_t fileidsmelliness_spaceiddistance_spaceidtime_spaceidspaceid;
683      hid_t adam_grpidable_grpidcain_grpid;
684      hid_t time_scaleidsmelliness_scaleiddistance_scaleid;
685      hid_t goat_dsidcamel_dsidcparmsid;
686      hsize_t dims[NDIMS], max_dims[NDIMS];
687
688      /* Create file and group. */
689      if ((fileid = H5Fcreate(FILE_NAMEH5F_ACC_TRUNCH5P_DEFAULT,
690       H5P_DEFAULT)) < 0) ERR;
691      if ((adam_grpid = H5Gcreate(fileidFATHER, 0)) < 0) ERR;
692      if ((able_grpid = H5Gcreate(adam_grpidGOOD_CHILD, 0)) < 0) ERR;
693      if ((cain_grpid = H5Gcreate(adam_grpidBAD_CHILD, 0)) < 0) ERR;
694
695      /* Create 3 1D spaces for the 3 dimension scale datasets. Time
696       * and smelliness starts out as 0. They are unlimited dimension
697       * scales. */
698      dims[0] = 0;
699      max_dims[0] = H5S_UNLIMITED;
700      if ((time_spaceid = H5Screate_simple(1, dimsmax_dims)) < 0) ERR;
701      dims[0] = 0;
702      max_dims[0] = H5S_UNLIMITED;
703      if ((smelliness_spaceid = H5Screate_simple(1, dimsmax_dims)) < 0) ERR;
704      dims[0] = DISTANCE_LEN;
705      max_dims[0] = DISTANCE_LEN;
706      if ((distance_spaceid = H5Screate_simple(1, dimsmax_dims)) < 0) ERR;
707
708      /* Enable chunking for unlimited time and smelliness scale. */
709      if ((cparmsid = H5Pcreate(H5P_DATASET_CREATE)) < 0) ERR;
710      dims[0] = 1;
711      if (H5Pset_chunk(cparmsid, 1, dims) < 0) ERR;
712
713      /* Create our dimension scales. */
714      if ((time_scaleid = H5Dcreate(adam_grpidTIME_NAMEH5T_NATIVE_INT,
715     time_spaceidcparmsid)) < 0) ERR;
716      if (H5DSset_scale(time_scaleidTIME_NAME) < 0) ERR;
717      if ((smelliness_scaleid = H5Dcreate(adam_grpidSMELLINESS_NAMEH5T_NATIVE_FLOAT,
718   smelliness_spaceidcparmsid)) < 0) ERR;
719      if (H5DSset_scale(smelliness_scaleidSMELLINESS_NAME) < 0) ERR;
720      if ((distance_scaleid = H5Dcreate(adam_grpidDISTANCE_NAMEH5T_NATIVE_FLOAT,
721 distance_spaceidH5P_DEFAULT)) < 0) ERR;
722      if (H5DSset_scale(distance_scaleidDISTANCE_NAME) < 0) ERR;
723
724      /* Create a space coresponding to these three dimensions. */
725      dims[TIME_DIM] = 0;
726      dims[SMELLINESS_DIM] = 0;
727      dims[DISTANCE_DIM] = DISTANCE_LEN;
728      max_dims[TIME_DIM] = H5S_UNLIMITED;
729      max_dims[SMELLINESS_DIM] = H5S_UNLIMITED;
730      max_dims[DISTANCE_DIM] = DISTANCE_LEN;
731      if ((spaceid = H5Screate_simple(NDIMSdimsmax_dims)) < 0) ERR;
732
733      /* Set up chunking for our 3D vars. */
734      dims[TIME_DIM] = 1;
735      dims[SMELLINESS_DIM] = 1;
736      if (H5Pset_chunk(cparmsidNDIMSdims) < 0) ERR;
737
738      /* Create two variables which use them, and attach the dimension scales. */
739      if ((goat_dsid = H5Dcreate(able_grpidGOAT_NAMEH5T_NATIVE_FLOAT,
740  spaceidcparmsid)) < 0) ERR;
741      if (H5DSattach_scale(goat_dsidtime_scaleid, 0) < 0) ERR;
742      if (H5DSattach_scale(goat_dsidsmelliness_scaleid, 1) < 0) ERR;
743      if (H5DSattach_scale(goat_dsiddistance_scaleid, 2) < 0) ERR;
744      if ((camel_dsid = H5Dcreate(cain_grpidCAMEL_NAMEH5T_NATIVE_FLOAT,
745   spaceidcparmsid)) < 0) ERR;
746      if (H5DSattach_scale(camel_dsidtime_scaleid, 0) < 0) ERR;
747      if (H5DSattach_scale(camel_dsidsmelliness_scaleid, 1) < 0) ERR;
748      if (H5DSattach_scale(camel_dsiddistance_scaleid, 2) < 0) ERR;
749
750      /* Close up the shop. */
751      if (H5Dclose(goat_dsid) < 0 ||
752   H5Dclose(camel_dsid) < 0 ||
753   H5Dclose(smelliness_scaleid) < 0 ||
754   H5Dclose(distance_scaleid) < 0 ||
755   H5Dclose(time_scaleid) < 0 ||
756   H5Sclose(spaceid) < 0 ||
757   H5Gclose(cain_grpid) < 0 ||
758   H5Gclose(able_grpid) < 0 ||
759   H5Gclose(adam_grpid) < 0 ||
760   H5Fclose(fileid) < 0) ERR;
761   }
762
763   SUMMARIZE_ERR;
764   printf("*** Checking 3D datasets in groups created with shared dimscales...");
765
766   {
767      hid_t fileidgrpid;
768
769      /* Reopen the file and group. */
770      if ((fileid = H5Fopen(FILE_NAMEH5F_ACC_RDWRH5P_DEFAULT)) < 0) ERR;
771      if ((grpid = H5Gopen(fileidFATHER)) < 0) ERR;
772
773      /* If we can't scan the group, crash into a flaming heap of
774       * smoking, smoldering rubbish. */
775      if (rec_scan_group(grpid)) ERR;
776
777      /* Close up the shop. */
778      if (H5Gclose(grpid) < 0 ||
779   H5Fclose(fileid) < 0) ERR;
780   }
781
782   SUMMARIZE_ERR;
783#endif
784   FINAL_RESULTS;
785}
786


HyperKWIC - Version 7.20DA executed at 11:37 on 27 Oct 2017 | Polyhedron Solutions - INTERNAL USE | COMMERCIAL (Any O/S) SN 4AKIed