Re: questions about H5DSiterate_scales

this question was for Quincey, users of the mailing list can just ignore it, 
sorry about that
the format is %a with HDfprintf, btw

At 03:19 PM 7/12/2005, you wrote:
>what 's the format for printing haddr_t ?
>
> printf("visiting sb1.objno = %lu sb2.objno = %lu\n", 
>          sb1.objno, sb2.objno);
>
>
>
>At 10:58 AM 7/12/2005, you wrote:
>>Pedro,
>>    Can you look at Ed's program and see if you can help him?
>>
>>        Quincey
>>
>>[ Charset ISO-8859-15 unsupported, converting... ]
>>> Howdy all!
>>> 
>>> I've isolated the code into it's own program, and you can see the
>>> problem I'm having by compiling and running the program appended below
>>> (tst_h_dimscales2.c) including its header file, tests.h, also appended
>>> below.
>>> 
>>> This program creates a very simple HDF5 file (tst_h_dimscales2.h5),
>>> with two 1D datasets. One dataset is marked as a dimension scale, the
>>> other attaches it as it's dimscale. Then the file is closed. The
>>> h5dump of the file at this point is included below. Everything looks
>>> fine to me, including all the names.
>>> 
>>> The file is then reopened and I iterate through the objects. When I
>>> find the dimscale I check the name, and it's fine. When I encounter
>>> the other dataset, "var1", I check that it has one scale, and then
>>> call iterate_scales to execute the function alien_visitor on that
>>> dataset/dimscale combination.
>>> 
>>> The function, alien_visitor, gets the associated names of it's did and
>>> dsid parameters. The did parameter yields a name, as expected:
>>> "/var1". But the dsid parameter, which supposedly points to the
>>> dimscale dataset, returns a name of garbage characters.
>>> 
>>> How do I know that dsid is really pointing to the dimscale dataset,
>>> named "dimscale" in this example?
>>> 
>>> Is this a H5DS bug, or am I doing something horribly, tragically, but
>>> hopefully not inexplicably wrong?
>>> 
>>> Thanks,
>>> 
>>> Ed
>>> 
>>> Here's the output:
>>> 
>>> ./tst_h_dimscales2
>>> *** Creating a file with one var with one dimension scale...ok.
>>> *** Checking that one var, one dimscale file can be read...
>>> Encountered: HDF5 object obj_class 2 obj_name dimscale
>>> Encountered: HDF5 object obj_class 2 obj_name var1
>>> unexpected result, tst_h_dimscales2.c, line: 34
>>> visiting did 0x6000003 dim 0 dsid 0x6000004 name of did /var1 
>>> :???z????????
>>> 1 failures
>>> 
>>> h5dump of tst_h_dimscales2.h5:
>>> HDF5 "tst_h_dimscales2.h5" {
>>> GROUP "/" {
>>>    DATASET "dimscale" {
>>>       DATATYPE  H5T_STD_I32LE
>>>       DATASPACE  SIMPLE { ( 3 ) / ( H5S_UNLIMITED ) }
>>>       DATA {
>>>       (0): 0, 0, 0
>>>       }
>>>       ATTRIBUTE "CLASS" {
>>>          DATATYPE  H5T_STRING {
>>>                STRSIZE 16;
>>>                STRPAD H5T_STR_NULLTERM;
>>>                CSET H5T_CSET_ASCII;
>>>                CTYPE H5T_C_S1;
>>>             }
>>>          DATASPACE  SCALAR
>>>          DATA {
>>>          (0): "DIMENSION_SCALE"
>>>          }
>>>       }
>>>       ATTRIBUTE "NAME" {
>>>          DATATYPE  H5T_STRING {
>>>                STRSIZE 24;
>>>                STRPAD H5T_STR_NULLTERM;
>>>                CSET H5T_CSET_ASCII;
>>>                CTYPE H5T_C_S1;
>>>             }
>>>          DATASPACE  SCALAR
>>>          DATA {
>>>          (0): "dimscale_name_attribute"
>>>          }
>>>       }
>>>       ATTRIBUTE "REFERENCE_LIST" {
>>>          DATATYPE  H5T_COMPOUND {
>>>             H5T_REFERENCE "dataset";
>>>             H5T_STD_I32LE "dimension";
>>>          }
>>>          DATASPACE  SIMPLE { ( 1 ) / ( 1 ) }
>>>          DATA {
>>>          (0): {
>>>                DATASET 1576 /var1 ,
>>>                0
>>>             }
>>>          }
>>>       }
>>>    }
>>>    DATASET "var1" {
>>>       DATATYPE  H5T_STD_I32LE
>>>       DATASPACE  SIMPLE { ( 3 ) / ( H5S_UNLIMITED ) }
>>>       DATA {
>>>       (0): 0, 0, 0
>>>       }
>>>       ATTRIBUTE "DIMENSION_LIST" {
>>>          DATATYPE  H5T_VLEN { H5T_REFERENCE}
>>>          DATASPACE  SIMPLE { ( 1 ) / ( 1 ) }
>>>          DATA {
>>>          (0): (DATASET 976 /dimscale )
>>>          }
>>>       }
>>>       ATTRIBUTE "DIMENSION_LABELS" {
>>>          DATATYPE  H5T_STRING {
>>>                STRSIZE H5T_VARIABLE;
>>>                STRPAD H5T_STR_NULLTERM;
>>>                CSET H5T_CSET_ASCII;
>>>                CTYPE H5T_C_S1;
>>>             }
>>>          DATASPACE  SIMPLE { ( 1 ) / ( 1 ) }
>>>          DATA {
>>>          (0): "dimscale_label"
>>>          }
>>>       }
>>>    }
>>> }
>>> }
>>> 
>>> 
>>> tests.h:
>>> 
>>> /* This is part of the netCDF package.
>>>    Copyright 2005 University Corporation for Atmospheric Research/Unidata
>>>    See COPYRIGHT file for conditions of use.
>>> 
>>>    Common includes, defines, etc., for test code in the libsrc4
>>>    directory.
>>> 
>>>    $Id: tests.h,v 1.6 2005/06/06 20:36:22 ed Exp $
>>> */
>>> #ifndef _NC4_TESTS_
>>> #define _NC4_TESTS_
>>> 
>>> #include <config.h>
>>> #include <assert.h>
>>> #include <stdio.h>
>>> #include <string.h>
>>> #include "error.h"
>>> 
>>> int total_err = 0, err = 0;
>>> 
>>> /* This is handy for print statements. */
>>> char *format_name[] = {"", "classic", "64-bit offset", "netCDF-4", 
>>> "netCDF-4 strict NC3"};
>>> 
>>> #define ERR do { \
>>> fflush(stdout); /* Make sure our stdout is synced with stderr. */ \
>>> err++; \
>>> fprintf(stderr, "unexpected result, %s, line: %d\n", __FILE__, __LINE__); \
>>> } while (0)
>>> 
>>> #define SUMMARIZE_ERR do { \
>>>    if (err) \
>>>    { \
>>>       printf("%d failures\n", err); \
>>>       total_err += err; \
>>>       err = 0; \
>>>    } \
>>>    else \
>>>       printf("ok.\n"); \
>>> } while (0)
>>> 
>>> 
>>> #endif /* _NC4_TESTS_ */
>>> 
>>> tst_h_dimscales2.c:
>>> 
>>> /* This is part of the netCDF package.
>>>    Copyright 2005 University Corporation for Atmospheric Research/Unidata
>>>    See COPYRIGHT file for conditions of use.
>>> 
>>>    Test HDF5 file code. These are not intended to be exhaustive tests,
>>>    but they use HDF5 the same way that netCDF-4 does, so if these
>>>    tests don't work, than netCDF-4 won't work either.
>>> 
>>>    $Id: tst_h_dimscales.c,v 1.5 2005/07/01 09:33:05 ed Exp $
>>> */
>>> #include "tests.h"
>>> #include "H5DS.h"
>>> 
>>> #define FILE_NAME "tst_h_dimscales2.h5"
>>> #define DIMSCALE_NAME "dimscale"
>>> #define VAR1_NAME "var1"
>>> #define NDIMS 1
>>> #define DIM1_LEN 3
>>> #define NAME_ATTRIBUTE "dimscale_name_attribute"
>>> #define DIMSCALE_LABEL "dimscale_label"
>>> 
>>> herr_t alien_visitor(hid_t did, unsigned dim, hid_t dsid, 
>>>                    void *visitor_data)
>>> {
>>>    char name1[NC_MAX_NAME], name2[NC_MAX_NAME];
>>> 
>>>    /* This should get "/var1", the name of the dataset that the scale
>>>     * is attached to. */
>>>    if (H5Iget_name(did, name1, NC_MAX_NAME) < 0) ERR;
>>>    if (strcmp(&name1[1], VAR1_NAME)) ERR;
>>>    
>>>    /* This should get "/dimscale" but it doesn't seem to be! */
>>>    if (H5Iget_name(dsid, name2, NC_MAX_NAME) < 0) ERR;
>>>    if (strcmp(&name2[1], DIMSCALE_NAME)) ERR;
>>> 
>>>    printf("visiting did 0x%x dim %d dsid 0x%x name of did %s \n", 
>>>         did, dim, dsid, name1);
>>>    printf("name of dsid: %s\n", name2);
>>>    return 0;
>>> }
>>> 
>>> int
>>> main()
>>> {
>>>    printf("*** Creating a file with one var with one dimension scale...");
>>>    
>>>    {
>>>       hid_t fileid, spaceid, datasetid, dimscaleid, cparmsid;
>>>       hsize_t dims[NDIMS] = {DIM1_LEN}, maxdims[NDIMS] = {H5S_UNLIMITED};
>>> 
>>>       /* Create file. */
>>>       if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, 
>>>                             H5P_DEFAULT)) < 0) ERR;
>>> 
>>>       /* Create the space that will be used both for the dimscale and
>>>        * the 1D dataset that will attach it. */
>>>       if ((spaceid = H5Screate_simple(NDIMS, dims, maxdims)) < 0) ERR;
>>> 
>>>       /* Modify dataset creation properties, i.e. enable chunking. */
>>>       dims[0] = 1;
>>>       if ((cparmsid = H5Pcreate(H5P_DATASET_CREATE)) < 0) ERR;
>>>       if (H5Pset_chunk(cparmsid, NDIMS, dims) < 0) ERR;
>>> 
>>>       /* Create our dimension scale, as an unlimited dataset. */
>>>       if ((dimscaleid = H5Dcreate(fileid, DIMSCALE_NAME, H5T_NATIVE_INT, 
>>>                                 spaceid, cparmsid)) < 0) ERR;
>>>       if (H5DSset_scale(dimscaleid, NAME_ATTRIBUTE) < 0) ERR;
>>> 
>>>       /* Create a variable which uses it. */
>>>       if ((datasetid = H5Dcreate(fileid, VAR1_NAME, H5T_NATIVE_INT, 
>>>                               spaceid, cparmsid)) < 0) ERR;
>>>       if (H5DSattach_scale(datasetid, dimscaleid, 0) < 0) ERR;
>>>       if (H5DSset_label(datasetid, 0, DIMSCALE_LABEL) < 0) ERR;
>>> 
>>>       /* Fold up our tents. */
>>>       if (H5Dclose(dimscaleid) < 0 ||
>>>         H5Dclose(datasetid) < 0 ||
>>>         H5Sclose(spaceid) < 0 ||
>>>         H5Fclose(fileid) < 0) ERR;
>>>    }
>>> 
>>>    SUMMARIZE_ERR;
>>>    printf("*** Checking that one var, one dimscale file can be read...");
>>> 
>>>    {
>>>       hid_t fileid, spaceid = 0, datasetid = 0;
>>>       hsize_t num_obj, i;
>>>       int obj_class;
>>>       char obj_name[NC_MAX_NAME + 1];
>>>       char dimscale_name[NC_MAX_NAME+1];
>>>       htri_t is_scale;
>>>       char label[NC_MAX_NAME+1];
>>>       int visitor_data = 0;
>>>       int num_scales;
>>>       hsize_t dims[1], maxdims[1];
>>> 
>>>       /* Open the file. */
>>>       if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) ERR;
>>>       
>>>       /* Loop through objects in the root group. */
>>>       if (H5Gget_num_objs(fileid, &num_obj) < 0) ERR;
>>>       for (i=0; i<num_obj; i++)
>>>       {
>>>       /* Get the type (i.e. group, dataset, etc.), and the name of
>>>         * the object. */
>>>       if ((obj_class = H5Gget_objtype_by_idx(fileid, i)) < 0) ERR;
>>>       if (H5Gget_objname_by_idx(fileid, i, obj_name, NC_MAX_NAME) < 0) ERR;
>>> 
>>>       printf("\nEncountered: HDF5 object obj_class %d obj_name %s\n", 
>>>               obj_class, obj_name);
>>> 
>>>       /* Deal with object based on its obj_class. */
>>>       switch(obj_class)
>>>       {
>>>           case H5G_GROUP:
>>>              break;
>>>           case H5G_DATASET:
>>>              /* Open the dataset. */
>>>              if ((datasetid = H5Dopen(fileid, obj_name)) < 0) ERR;
>>> 
>>>              /* This should be an unlimited dataset. */
>>>              if ((spaceid = H5Dget_space(datasetid)) < 0) ERR;
>>>              if (H5Sget_simple_extent_dims(spaceid, dims, maxdims) < 0) ERR;
>>>              if (maxdims[0] != H5S_UNLIMITED) ERR;
>>> 
>>>              /* Is this a dimscale? */
>>>              if ((is_scale = H5DSis_scale(datasetid)) < 0) ERR;
>>>              if (is_scale && strcmp(obj_name, DIMSCALE_NAME)) ERR;
>>>              if (is_scale)
>>>              {
>>>                 /* A dimscale comes with a NAME attribute, in
>>>                  * addition to it's real name. */
>>>                 if (H5DSget_scale_name(datasetid, dimscale_name, 
>>> NC_MAX_NAME) < 0) ERR;
>>>                 if (strcmp(dimscale_name, NAME_ATTRIBUTE)) ERR;
>>>              }
>>>              else
>>>              {
>>>                 /* Here's how to get the number of scales attached
>>>                  * to the dataset's dimension 0. */
>>>                 if ((num_scales = H5DSget_num_scales(datasetid, 0)) < 0) 
>>> ERR;
>>>                 if (num_scales != 1) ERR;
>>> 
>>>                 /* Go through all dimscales for this var and learn about 
>>> them. */
>>>                 if (H5DSiterate_scales(datasetid, 0, NULL, alien_visitor, 
>>>                                       &visitor_data) < 0) ERR;
>>>                 
>>>                 /* There's also a label for dimension 0. */
>>>                 if (H5DSget_label(datasetid, 0, label, NC_MAX_NAME) < 0) 
>>> ERR;
>>> 
>>>                 /*printf("found non-scale dataset %s, label %s\n", 
>>> obj_name, label);*/
>>>              }
>>>              if (H5Dclose(datasetid) < 0) ERR;
>>>              break;
>>>           case H5G_TYPE:
>>>              break;
>>>           case H5G_LINK:
>>>              break;
>>>           default:
>>>              printf("Unknown object class %d in rec_read_metadata!", 
>>> obj_class);
>>>       }
>>>       }
>>> 
>>>       /* Close up the shop. */
>>>       if (H5Sclose(spaceid) < 0 ||
>>>         H5Fclose(fileid) < 0) ERR;
>>>    }
>>> 
>>>    SUMMARIZE_ERR;
>>> 
>>>    /* Print out our number of errors, if any, and exit badly. */
>>>    if (total_err)
>>>    {
>>>       printf("%d errors detected! Sorry!\n", total_err);
>>>       return 2;
>>>    }
>>>    
>>>    printf("*** Tests successful!\n");
>>>    return 0;
>>> }
>>> 
>>> 
>>> 
>>> -- 
>>> Ed Hartnett  -- ed@xxxxxxxxxxxxxxxx
>>> 
>>> 
>
></Pedro Vicente Nunes>
>--------------------------------------------------------------
>hdf.ncsa.uiuc.edu
>Tel. 1-217-265 0311

</Pedro Vicente Nunes>
--------------------------------------------------------------
hdf.ncsa.uiuc.edu
Tel. 1-217-265 0311