Пример #1
0
  void PWOrbitalBuilder::transform2GridData(PWBasis::GIndex_t& nG, int spinIndex, PWOrbitalSet& pwFunc)
  {
    ostringstream splineTag;
    splineTag << "eigenstates_"<<nG[0]<<"_"<<nG[1]<<"_"<<nG[2];
    herr_t status = H5Eset_auto(NULL, NULL);

    app_log() << " splineTag " << splineTag.str() << endl;

    hid_t es_grp_id;
    status = H5Gget_objinfo (hfileID, splineTag.str().c_str(), 0, NULL);
    if(status)
    {
      es_grp_id = H5Gcreate(hfileID,splineTag.str().c_str(),0);
      HDFAttribIO<PWBasis::GIndex_t> t(nG);
      t.write(es_grp_id,"grid");
    } 
    else
    {
      es_grp_id = H5Gopen(hfileID,splineTag.str().c_str());
    }

    string tname=myParam->getTwistName();
    hid_t twist_grp_id;
    status = H5Gget_objinfo (es_grp_id, tname.c_str(), 0, NULL);
    if(status)
      twist_grp_id = H5Gcreate(es_grp_id,tname.c_str(),0);
    else
      twist_grp_id = H5Gopen(es_grp_id,tname.c_str());

    HDFAttribIO<PosType> hdfobj_twist(TwistAngle);
    hdfobj_twist.write(twist_grp_id,"twist_angle");

    ParticleSet::ParticleLayout_t& lattice(targetPtcl.Lattice);
    RealType dx=1.0/static_cast<RealType>(nG[0]-1);
    RealType dy=1.0/static_cast<RealType>(nG[1]-1);
    RealType dz=1.0/static_cast<RealType>(nG[2]-1);

#if defined(VERYTINYMEMORY)
    typedef Array<ValueType,3> StorageType;
    StorageType inData(nG[0],nG[1],nG[2]);
   
    int ib=0;
    while(ib<myParam->numBands) 
    {
      string bname(myParam->getBandName(ib));
      status = H5Gget_objinfo (twist_grp_id, bname.c_str(), 0, NULL);
      hid_t band_grp_id, spin_grp_id=-1;
      if(status)
      {
        band_grp_id =  H5Gcreate(twist_grp_id,bname.c_str(),0);
      }
      else
      {
        band_grp_id =  H5Gopen(twist_grp_id,bname.c_str());
      }

      hid_t parent_id=band_grp_id;
      if(myParam->hasSpin)
      {
        bname=myParam->getSpinName(spinIndex);
        status = H5Gget_objinfo (band_grp_id, bname.c_str(), 0, NULL);
        if(status)
        {
          spin_grp_id =  H5Gcreate(band_grp_id,bname.c_str(),0);
        }
        else
        {
          spin_grp_id =  H5Gopen(band_grp_id,bname.c_str());
        }
        parent_id=spin_grp_id;
      }

      for(int ig=0; ig<nG[0]; ig++)
      {
        RealType x=ig*dx;
        for(int jg=0; jg<nG[1]; jg++)
        {
          RealType y=jg*dy;
          for(int kg=0; kg<nG[2]; kg++)
          {
            inData(ig,jg,kg)= pwFunc.evaluate(ib,lattice.toCart(PosType(x,y,kg*dz)));
          }
        }
      }

      app_log() << "  Add spline data " << ib << " h5path=" << tname << "/eigvector" << endl;
      HDFAttribIO<StorageType> t(inData);
      t.write(parent_id,myParam->eigvecTag.c_str());

      if(spin_grp_id>=0) H5Gclose(spin_grp_id);
      H5Gclose(band_grp_id);
      ++ib;
    }
#else
    typedef Array<ValueType,3> StorageType;
    vector<StorageType*> inData;
    int nb=myParam->numBands;
    for(int ib=0; ib<nb; ib++)
      inData.push_back(new StorageType(nG[0],nG[1],nG[2]));

    PosType tAngle=targetPtcl.Lattice.k_cart(TwistAngle);
    PWOrbitalSet::ValueVector_t phi(nb);
    for(int ig=0; ig<nG[0]; ig++)
    {
      RealType x=ig*dx;
      for(int jg=0; jg<nG[1]; jg++)
      {
        RealType y=jg*dy;
        for(int kg=0; kg<nG[2]; kg++)
        {
          targetPtcl.R[0]=lattice.toCart(PosType(x,y,kg*dz));
          pwFunc.evaluate(targetPtcl,0,phi);
          RealType x(dot(targetPtcl.R[0],tAngle));
          ValueType phase(std::cos(x),-std::sin(x)); 
          for(int ib=0; ib<nb; ib++)
             (*inData[ib])(ig,jg,kg)=phase*phi[ib];
        }
      }
    }

    for(int ib=0; ib<nb; ib++)
    {
      string bname(myParam->getBandName(ib));
      status = H5Gget_objinfo (twist_grp_id, bname.c_str(), 0, NULL);
      hid_t band_grp_id, spin_grp_id=-1;
      if(status)
      {
        band_grp_id =  H5Gcreate(twist_grp_id,bname.c_str(),0);
      }
      else
      {
        band_grp_id =  H5Gopen(twist_grp_id,bname.c_str());
      }

      hid_t parent_id=band_grp_id;
      if(myParam->hasSpin)
      {
        bname=myParam->getSpinName(spinIndex);
        status = H5Gget_objinfo (band_grp_id, bname.c_str(), 0, NULL);
        if(status)
        {
          spin_grp_id =  H5Gcreate(band_grp_id,bname.c_str(),0);
        }
        else
        {
          spin_grp_id =  H5Gopen(band_grp_id,bname.c_str());
        }
        parent_id=spin_grp_id;
      }

      app_log() << "  Add spline data " << ib << " h5path=" << tname << "/eigvector" << endl;
      HDFAttribIO<StorageType> t(*(inData[ib]));
      t.write(parent_id,myParam->eigvecTag.c_str());

      if(spin_grp_id>=0) H5Gclose(spin_grp_id);
      H5Gclose(band_grp_id);
    }
    for(int ib=0; ib<nb; ib++) delete inData[ib];
#endif
    H5Gclose(twist_grp_id);
    H5Gclose(es_grp_id);
  }
Пример #2
0
int
main()
{
   printf("\n*** Checking HDF5 dimscales some more.\n");
   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 num_scales;
      hsize_t dims[1], maxdims[1];
      H5G_stat_t statbuf;
      HDF5_OBJID_T dimscale_obj, vars_dimscale_obj;

      /* 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 = H5Dopen1(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 its real name. */
		  if (H5DSget_scale_name(datasetid, dimscale_name, NC_MAX_NAME) < 0) ERR;
		  if (strcmp(dimscale_name, NAME_ATTRIBUTE)) ERR;

		  /* fileno and objno uniquely identify an object and a
		   * HDF5 file. */
		  if (H5Gget_objinfo(datasetid, ".", 1, &statbuf) < 0) ERR;
		  dimscale_obj.fileno[0] = statbuf.fileno[0];
		  dimscale_obj.objno[0] = statbuf.objno[0];
		  dimscale_obj.fileno[1] = statbuf.fileno[1];
		  dimscale_obj.objno[1] = statbuf.objno[1];
		  /*printf("statbuf.fileno = %d statbuf.objno = %d\n",
		    statbuf.fileno, statbuf.objno);*/

	       }
	       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,
					 &vars_dimscale_obj) < 0) ERR;
		  /*printf("vars_dimscale_obj.fileno = %d vars_dimscale_obj.objno = %d\n",
		    vars_dimscale_obj.fileno, vars_dimscale_obj.objno);*/
		  if (vars_dimscale_obj.fileno[0] != dimscale_obj.fileno[0] ||
		      vars_dimscale_obj.objno[0] != dimscale_obj.objno[0] ||
		      vars_dimscale_obj.fileno[1] != dimscale_obj.fileno[1] ||
		      vars_dimscale_obj.objno[1] != dimscale_obj.objno[1]) 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!", obj_class);
	 }
      }

      /* Close up the shop. */
      if (H5Sclose(spaceid) < 0 ||
	  H5Fclose(fileid) < 0) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** Creating a file with one var with two dimension scales...");
   
   {
#define LAT_LEN 3
#define LON_LEN 2
#define DIMS_2 2
#define LAT_NAME "lat"
#define LON_NAME "lon"
#define PRES_NAME "pres"
      
      hid_t fileid, lat_spaceid, lon_spaceid, pres_spaceid;
      hid_t pres_datasetid, lat_dimscaleid, lon_dimscaleid;
      hsize_t dims[DIMS_2];

      /* Create file. */
      if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT,
			      H5P_DEFAULT)) < 0) ERR;

      /* Create the spaces that will be used for the dimscales. */
      dims[0] = LAT_LEN;
      if ((lat_spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR;
      dims[0] = LON_LEN;
      if ((lon_spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR;

      /* Create the space for the dataset. */
      dims[0] = LAT_LEN;
      dims[1] = LON_LEN;
      if ((pres_spaceid = H5Screate_simple(DIMS_2, dims, dims)) < 0) ERR;

      /* Create our dimension scales. */
      if ((lat_dimscaleid = H5Dcreate(fileid, LAT_NAME, H5T_NATIVE_INT,
				      lat_spaceid, H5P_DEFAULT)) < 0) ERR;
      if (H5DSset_scale(lat_dimscaleid, NULL) < 0) ERR;
      if ((lon_dimscaleid = H5Dcreate(fileid, LON_NAME, H5T_NATIVE_INT,
				      lon_spaceid, H5P_DEFAULT)) < 0) ERR;
      if (H5DSset_scale(lon_dimscaleid, NULL) < 0) ERR;

      /* Create a variable which uses these two dimscales. */
      if ((pres_datasetid = H5Dcreate(fileid, PRES_NAME, H5T_NATIVE_FLOAT,
				      pres_spaceid, H5P_DEFAULT)) < 0) ERR;
      if (H5DSattach_scale(pres_datasetid, lat_dimscaleid, 0) < 0) ERR;
      if (H5DSattach_scale(pres_datasetid, lon_dimscaleid, 1) < 0) ERR;

      /* Fold up our tents. */
      if (H5Dclose(lat_dimscaleid) < 0 ||
	  H5Dclose(lon_dimscaleid) < 0 ||
	  H5Dclose(pres_datasetid) < 0 ||
	  H5Sclose(lat_spaceid) < 0 ||
	  H5Sclose(lon_spaceid) < 0 ||
	  H5Sclose(pres_spaceid) < 0 ||
	  H5Fclose(fileid) < 0) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** Checking that one var, two dimscales file can be read...");

   {
#define NDIMS2 2
      hid_t fileid, spaceid = 0, datasetid = 0;
      hsize_t num_obj, i;
      int obj_class;
      char obj_name[NC_MAX_NAME + 1];
      htri_t is_scale;
      int num_scales;
      hsize_t dims[NDIMS2], maxdims[NDIMS2];
      H5G_stat_t statbuf;
      HDF5_OBJID_T dimscale_obj[2], vars_dimscale_obj[2];
      int dimscale_cnt = 0;
      int d, ndims;

      /* 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 = H5Dopen1(fileid, obj_name)) < 0) ERR;

	       /* Get space info. */
	       if ((spaceid = H5Dget_space(datasetid)) < 0) ERR;
	       if (H5Sget_simple_extent_dims(spaceid, dims, maxdims) < 0) ERR;
	       if ((ndims = H5Sget_simple_extent_ndims(spaceid)) < 0) ERR;
	       if (ndims > NDIMS2) ERR;

	       /* Is this a dimscale? */
	       if ((is_scale = H5DSis_scale(datasetid)) < 0) ERR;
	       if (is_scale)
	       {
		  /* fileno and objno uniquely identify an object and a
		   * HDF5 file. */
		  if (H5Gget_objinfo(datasetid, ".", 1, &statbuf) < 0) ERR;
		  dimscale_obj[dimscale_cnt].fileno[0] = statbuf.fileno[0];
		  dimscale_obj[dimscale_cnt].objno[0] = statbuf.objno[0];
		  dimscale_obj[dimscale_cnt].fileno[1] = statbuf.fileno[1];
		  dimscale_obj[dimscale_cnt].objno[1] = statbuf.objno[1];
/* 		  printf("dimscale_obj[%d].fileno = %d dimscale_obj[%d].objno = %d\n", */
/* 			 dimscale_cnt, dimscale_obj[dimscale_cnt].fileno, dimscale_cnt,  */
/* 			 dimscale_obj[dimscale_cnt].objno); */
		  dimscale_cnt++;
	       }
	       else
	       {
		  /* Here's how to get the number of scales attached
		   * to the dataset's dimension 0 and 1. */
		  if ((num_scales = H5DSget_num_scales(datasetid, 0)) < 0) ERR;
		  if (num_scales != 1) ERR;
		  if ((num_scales = H5DSget_num_scales(datasetid, 1)) < 0) ERR;
		  if (num_scales != 1) ERR;

		  /* Go through all dimscales for this var and learn about them. */
		  for (d = 0; d < ndims; d++)
		  {
		     if (H5DSiterate_scales(datasetid, d, NULL, alien_visitor2,
		     &(vars_dimscale_obj[d])) < 0) ERR;

		     /* Verify that the object ids passed from the
		      * alien_visitor2 function match the ones we found
		      * for the lat and lon datasets. */
		     if (vars_dimscale_obj[d].fileno[0] != dimscale_obj[d].fileno[0] ||
		     vars_dimscale_obj[d].objno[0] != dimscale_obj[d].objno[0]) ERR;
		     if (vars_dimscale_obj[d].fileno[1] != dimscale_obj[d].fileno[1] ||
		     vars_dimscale_obj[d].objno[1] != dimscale_obj[d].objno[1]) ERR;
		  }
	       }
	       if (H5Dclose(datasetid) < 0) ERR;
	       if (H5Sclose(spaceid) < 0) ERR;
	       break;
	    case H5G_TYPE:
	       break;
	    case H5G_LINK:
	       break;
	    default:
	       printf("Unknown object class %d!", obj_class);
	 }
      }

      /* Close up the shop. */
      if (H5Fclose(fileid) < 0) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** Creating a file with one var with two unlimited dimension scales...");
   {
#define U1_LEN 3
#define U2_LEN 2
#define DIMS2 2
#define U1_NAME "u1"
#define U2_NAME "u2"
#define VNAME "v1"
      
      hid_t fapl_id, fcpl_id, grpid, plistid, plistid2;
      hid_t fileid, lat_spaceid, lon_spaceid, pres_spaceid;
      hid_t pres_datasetid, lat_dimscaleid, lon_dimscaleid;
      hsize_t dims[DIMS2], maxdims[DIMS2], chunksize[DIMS2] = {10, 10};
      hid_t spaceid = 0, datasetid = 0;
      hsize_t num_obj, i;
      int obj_class;
      char obj_name[NC_MAX_NAME + 1];
      htri_t is_scale;
      int num_scales;
      H5G_stat_t statbuf;
      HDF5_OBJID_T dimscale_obj[2], vars_dimscale_obj[2];
      int dimscale_cnt = 0;
      int d, ndims;

      /* Create file access and create property lists. */
      if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR;
      if ((fcpl_id = H5Pcreate(H5P_FILE_CREATE)) < 0) ERR;
      
      /* Set latest_format in access propertly list. This ensures that
       * the latest, greatest, HDF5 versions are used in the file. */
      if (H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) ERR;

      /* Set H5P_CRT_ORDER_TRACKED in the creation property list. This
       * turns on HDF5 creation ordering in the file. */
      if (H5Pset_link_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED |
					       H5P_CRT_ORDER_INDEXED)) < 0) ERR;
      if (H5Pset_attr_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED |
					       H5P_CRT_ORDER_INDEXED)) < 0) ERR;

      /* Create file. */
      if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, fcpl_id, fapl_id)) < 0) ERR;

      /* Open the root group. */
      if ((grpid = H5Gopen2(fileid, "/", H5P_DEFAULT)) < 0) ERR;

      /* Create the spaces that will be used for the dimscales. */
      dims[0] = 0;
      maxdims[0] = H5S_UNLIMITED;
      if ((lat_spaceid = H5Screate_simple(1, dims, maxdims)) < 0) ERR;
      if ((lon_spaceid = H5Screate_simple(1, dims, maxdims)) < 0) ERR;

      /* Create the space for the dataset. */
      dims[0] = 0;
      dims[1] = 0;
      maxdims[0] = H5S_UNLIMITED;
      maxdims[1] = H5S_UNLIMITED;
      if ((pres_spaceid = H5Screate_simple(DIMS2, dims, maxdims)) < 0) ERR;

      /* Set up the dataset creation property list for the two dimensions. */
      if ((plistid = H5Pcreate(H5P_DATASET_CREATE)) < 0) ERR;
      if (H5Pset_chunk(plistid, 1, chunksize) < 0) ERR;
      if (H5Pset_attr_creation_order(plistid, H5P_CRT_ORDER_TRACKED|
				     H5P_CRT_ORDER_INDEXED) < 0) ERR;

      /* Create our dimension scales. */
      if ((lat_dimscaleid = H5Dcreate(grpid, U1_NAME, H5T_NATIVE_INT,
				      lat_spaceid, plistid)) < 0) ERR;
      if (H5DSset_scale(lat_dimscaleid, NULL) < 0) ERR;
      if ((lon_dimscaleid = H5Dcreate(grpid, U2_NAME, H5T_NATIVE_INT,
				      lon_spaceid, plistid)) < 0) ERR;
      if (H5DSset_scale(lon_dimscaleid, NULL) < 0) ERR;

      /* Set up the dataset creation property list for the variable. */
      if ((plistid2 = H5Pcreate(H5P_DATASET_CREATE)) < 0) ERR;
      if (H5Pset_chunk(plistid2, DIMS2, chunksize) < 0) ERR;
      if (H5Pset_attr_creation_order(plistid2, H5P_CRT_ORDER_TRACKED|
				     H5P_CRT_ORDER_INDEXED) < 0) ERR;

      /* Create a variable which uses these two dimscales. */
      if ((pres_datasetid = H5Dcreate(grpid, VNAME, H5T_NATIVE_DOUBLE, pres_spaceid,
				      plistid2)) < 0) ERR;
      if (H5DSattach_scale(pres_datasetid, lat_dimscaleid, 0) < 0) ERR;
      if (H5DSattach_scale(pres_datasetid, lon_dimscaleid, 1) < 0) ERR;

      /* Close down the show. */
      if (H5Pclose(fapl_id) < 0 ||
	  H5Pclose(fcpl_id) < 0 ||
	  H5Dclose(lat_dimscaleid) < 0 ||
	  H5Dclose(lon_dimscaleid) < 0 ||
	  H5Dclose(pres_datasetid) < 0 ||
	  H5Sclose(lat_spaceid) < 0 ||
	  H5Sclose(lon_spaceid) < 0 ||
	  H5Sclose(pres_spaceid) < 0 ||
	  H5Pclose(plistid) < 0 ||
	  H5Pclose(plistid2) < 0 ||
	  H5Gclose(grpid) < 0 ||
	  H5Fclose(fileid) < 0) ERR;

      /* Open the file. */
      if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) ERR;
      if ((grpid = H5Gopen2(fileid, "/", H5P_DEFAULT)) < 0) ERR;
      
      /* Loop through objects in the root group. */
      if (H5Gget_num_objs(grpid, &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(grpid, i)) < 0) ERR;
	 if (H5Gget_objname_by_idx(grpid, i, obj_name, NC_MAX_NAME) < 0) ERR;

	 /* Deal with object based on its obj_class. */
	 switch(obj_class)
	 {
	    case H5G_GROUP:
	       break;
	    case H5G_DATASET:
	       /* Open the dataset. */
	       if ((datasetid = H5Dopen1(grpid, obj_name)) < 0) ERR;

	       /* Get space info. */
	       if ((spaceid = H5Dget_space(datasetid)) < 0) ERR;
	       if (H5Sget_simple_extent_dims(spaceid, dims, maxdims) < 0) ERR;
	       if ((ndims = H5Sget_simple_extent_ndims(spaceid)) < 0) ERR;

	       /* Is this a dimscale? */
	       if ((is_scale = H5DSis_scale(datasetid)) < 0) ERR;
	       if (is_scale)
	       {
		  /* fileno and objno uniquely identify an object and a
		   * HDF5 file. */
		  if (H5Gget_objinfo(datasetid, ".", 1, &statbuf) < 0) ERR;
		  dimscale_obj[dimscale_cnt].fileno[0] = statbuf.fileno[0];
		  dimscale_obj[dimscale_cnt].objno[0] = statbuf.objno[0];
		  dimscale_obj[dimscale_cnt].fileno[1] = statbuf.fileno[1];
		  dimscale_obj[dimscale_cnt].objno[1] = statbuf.objno[1];
		  dimscale_cnt++;
	       }
	       else
	       {
		  /* Here's how to get the number of scales attached
		   * to the dataset's dimension 0 and 1. */
		  if ((num_scales = H5DSget_num_scales(datasetid, 0)) < 0) ERR;
		  if (num_scales != 1) ERR;
		  if ((num_scales = H5DSget_num_scales(datasetid, 1)) < 0) ERR;
		  if (num_scales != 1) ERR;

		  /* Go through all dimscales for this var and learn about them. */
		  for (d = 0; d < ndims; d++)
		  {
		     if (H5DSiterate_scales(datasetid, d, NULL, alien_visitor2,
					    &(vars_dimscale_obj[d])) < 0) ERR;

		     /* Verify that the object ids passed from the
		      * alien_visitor2 function match the ones we found
		      * for the lat and lon datasets. */
		     if (vars_dimscale_obj[d].fileno[0] != dimscale_obj[d].fileno[0] ||
			 vars_dimscale_obj[d].objno[0] != dimscale_obj[d].objno[0]) ERR;
		     if (vars_dimscale_obj[d].fileno[1] != dimscale_obj[d].fileno[1] ||
			 vars_dimscale_obj[d].objno[1] != dimscale_obj[d].objno[1]) ERR;
		  }

	       }

	       if (H5Dclose(datasetid) < 0) ERR;
	       break;
	    case H5G_TYPE:
	       break;
	    case H5G_LINK:
	       break;
	    default:
	       printf("Unknown object class %d!", obj_class);
	 }
     }

      /* Check the dimension lengths. */
      {
	 hid_t spaceid1;
	 hsize_t h5dimlen[DIMS2], h5dimlenmax[DIMS2];
	 int dataset_ndims;

	 /* Check U1. */
	 if ((datasetid = H5Dopen1(grpid, U1_NAME)) < 0) ERR;
	 if ((spaceid1 = H5Dget_space(datasetid)) < 0) ERR;
	 if ((dataset_ndims = H5Sget_simple_extent_dims(spaceid1, h5dimlen,
							h5dimlenmax)) < 0) ERR;
	 if (dataset_ndims != 1 || h5dimlen[0] != 0 || h5dimlenmax[0] != H5S_UNLIMITED) ERR;
	 if (H5Dclose(datasetid) ||
	     H5Sclose(spaceid1)) ERR;

	 /* Check U2. */
	 if ((datasetid = H5Dopen1(grpid, U2_NAME)) < 0) ERR;
	 if ((spaceid1 = H5Dget_space(datasetid)) < 0) ERR;
	 if ((dataset_ndims = H5Sget_simple_extent_dims(spaceid1, h5dimlen,
							h5dimlenmax)) < 0) ERR;
	 if (dataset_ndims != 1 || h5dimlen[0] != 0 || h5dimlenmax[0] != H5S_UNLIMITED) ERR;
	 if (H5Dclose(datasetid) ||
	     H5Sclose(spaceid1)) ERR;
	 
	 /* Check V1. */
	 if ((datasetid = H5Dopen1(grpid, VNAME)) < 0) ERR;
	 if ((spaceid1 = H5Dget_space(datasetid)) < 0) ERR;
	 if ((dataset_ndims = H5Sget_simple_extent_dims(spaceid1, h5dimlen,
							h5dimlenmax)) < 0) ERR;
	 if (dataset_ndims != 2 || h5dimlen[0] != 0 || h5dimlen[1] != 0 ||
	     h5dimlenmax[0] != H5S_UNLIMITED || h5dimlenmax[1] != H5S_UNLIMITED) ERR;

	 /* All done. */
	 if (H5Dclose(datasetid) ||
	     H5Sclose(spaceid1)) ERR;
      }

      /* Write two hyperslabs. */
      {
#define NUM_VALS 3
	 hid_t file_spaceid, mem_spaceid;
	 hsize_t h5dimlen[DIMS2], h5dimlenmax[DIMS2], xtend_size[DIMS2] = {1, NUM_VALS};
	 hsize_t start[DIMS2] = {0, 0};
	 hsize_t count[DIMS2] = {1, NUM_VALS};
	 double value[NUM_VALS];
	 int dataset_ndims;
	 int i;

	 /* Set up phony data. */
	 for (i = 0; i < NUM_VALS; i++)
	    value[i] = (float)i;

	 /* Open the dataset, check its dimlens. */
	 if ((datasetid = H5Dopen1(grpid, VNAME)) < 0) ERR;
	 if ((file_spaceid = H5Dget_space(datasetid)) < 0) ERR;
	 if ((dataset_ndims = H5Sget_simple_extent_dims(file_spaceid, h5dimlen,
							h5dimlenmax)) < 0) ERR;
	 if (dataset_ndims != 2 || h5dimlen[0] != 0 || h5dimlen[1] != 0 ||
	     h5dimlenmax[0] != H5S_UNLIMITED || h5dimlenmax[1] != H5S_UNLIMITED) ERR;

	 /* Extend the size of the dataset. */
	 if (H5Dextend(datasetid, xtend_size) < 0) ERR;
	 if ((file_spaceid = H5Dget_space(datasetid)) < 0) ERR;

	 /* Check the size. */
	 if ((dataset_ndims = H5Sget_simple_extent_dims(file_spaceid, h5dimlen,
							h5dimlenmax)) < 0) ERR;
	 if (dataset_ndims != 2 || h5dimlen[0] != 1 || h5dimlen[1] != NUM_VALS ||
	     h5dimlenmax[0] != H5S_UNLIMITED || h5dimlenmax[1] != H5S_UNLIMITED) ERR;

	 /* Set up the file and memory spaces. */
	 if (H5Sselect_hyperslab(file_spaceid, H5S_SELECT_SET,
				 start, NULL, count, NULL) < 0) ERR;
	 if ((mem_spaceid = H5Screate_simple(DIMS2, count, NULL)) < 0) ERR;

	 /* Write a slice of data. */
	 if (H5Dwrite(datasetid, H5T_NATIVE_DOUBLE, mem_spaceid, file_spaceid,
		      H5P_DEFAULT, value) < 0)

	 /* Check the size. */
	 if ((file_spaceid = H5Dget_space(datasetid)) < 0) ERR;
	 if ((dataset_ndims = H5Sget_simple_extent_dims(file_spaceid, h5dimlen,
							h5dimlenmax)) < 0) ERR;
	 if (dataset_ndims != 2 || h5dimlen[0] != 1 || h5dimlen[1] != NUM_VALS ||
	     h5dimlenmax[0] != H5S_UNLIMITED || h5dimlenmax[1] != H5S_UNLIMITED) ERR;

	 /* Extend the size of the dataset for the second slice. */
	 xtend_size[0]++;
	 if (H5Dextend(datasetid, xtend_size) < 0) ERR;
	 if ((file_spaceid = H5Dget_space(datasetid)) < 0) ERR;

	 /* Set up the file and memory spaces for a second slice. */
	 start[0]++;
	 if (H5Sselect_hyperslab(file_spaceid, H5S_SELECT_SET,
				 start, NULL, count, NULL) < 0) ERR;
	 if ((mem_spaceid = H5Screate_simple(DIMS2, count, NULL)) < 0) ERR;

	 /* Write a second slice of data. */
	 if (H5Dwrite(datasetid, H5T_NATIVE_DOUBLE, mem_spaceid, file_spaceid,
		      H5P_DEFAULT, value) < 0)

	 /* Check the size again. */
	 if ((file_spaceid = H5Dget_space(datasetid)) < 0) ERR;
	 if ((dataset_ndims = H5Sget_simple_extent_dims(file_spaceid, h5dimlen,
							h5dimlenmax)) < 0) ERR;
	 if (dataset_ndims != 2 || h5dimlen[0] != 2 || h5dimlen[1] != NUM_VALS ||
	     h5dimlenmax[0] != H5S_UNLIMITED || h5dimlenmax[1] != H5S_UNLIMITED) ERR;

	 /* All done. */
	 if (H5Dclose(datasetid) ||
	     H5Sclose(mem_spaceid) ||
	     H5Sclose(file_spaceid)) ERR;
      }

      /* Close up the shop. */
      if (H5Sclose(spaceid)) ERR;
      if (H5Gclose(grpid) < 0 ||
      H5Fclose(fileid) < 0) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** Checking dimension scales with attached dimension scales...");
   
   {
#define LAT_LEN 3
#define LON_LEN 2
#define TIME_LEN 5
#define LEN_LEN 10
#define DIMS_3 3
#define NUM_DIMSCALES1 4
#define LAT_NAME "lat"
#define LON_NAME "lon"
#define PRES_NAME1 "z_pres"
#define TIME_NAME "time"
#define LEN_NAME "u_len"
      
      hid_t fileid, lat_spaceid, lon_spaceid, time_spaceid, pres_spaceid, len_spaceid;
      hid_t pres_datasetid, lat_dimscaleid, lon_dimscaleid, time_dimscaleid, len_dimscaleid;
      hid_t fapl_id, fcpl_id;
      hsize_t dims[DIMS_3];
      hid_t spaceid = 0, datasetid = 0;
      hsize_t num_obj, i;
      int obj_class;
      char obj_name[NC_MAX_NAME + 1];
      htri_t is_scale;
      int num_scales;
      hsize_t maxdims[DIMS_3];
      H5G_stat_t statbuf;
      HDF5_OBJID_T dimscale_obj[NUM_DIMSCALES1], vars_dimscale_obj[NUM_DIMSCALES1];
      int dimscale_cnt = 0;
      int d, ndims;

      /* Create file access and create property lists. */
      if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR;
      if ((fcpl_id = H5Pcreate(H5P_FILE_CREATE)) < 0) ERR;
      
      /* Set latest_format in access propertly list. This ensures that
       * the latest, greatest, HDF5 versions are used in the file. */
      if (H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) ERR;

      /* Set H5P_CRT_ORDER_TRACKED in the creation property list. This
       * turns on HDF5 creation ordering in the file. */
      if (H5Pset_link_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED |
					       H5P_CRT_ORDER_INDEXED)) < 0) ERR;
      if (H5Pset_attr_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED |
					       H5P_CRT_ORDER_INDEXED)) < 0) ERR;

      /* Create file. */
      if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, fcpl_id, fapl_id)) < 0) ERR;

      /* Create the spaces that will be used for the dimscales. */
      dims[0] = LAT_LEN;
      if ((lat_spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR;
      dims[0] = LON_LEN;
      if ((lon_spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR;
      dims[0] = TIME_LEN;
      if ((time_spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR;
      dims[0] = LEN_LEN;
      if ((len_spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR;

      /* Create the space for the dataset. */
      dims[0] = LAT_LEN;
      dims[1] = LON_LEN;
      dims[2] = TIME_LEN;
      if ((pres_spaceid = H5Screate_simple(DIMS_3, dims, dims)) < 0) ERR;

      /* Create our dimension scales. */
      if ((lat_dimscaleid = H5Dcreate1(fileid, LAT_NAME, H5T_NATIVE_INT,
				      lat_spaceid, H5P_DEFAULT)) < 0) ERR;
      if (H5DSset_scale(lat_dimscaleid, NULL) < 0) ERR;
      if ((lon_dimscaleid = H5Dcreate1(fileid, LON_NAME, H5T_NATIVE_INT,
				      lon_spaceid, H5P_DEFAULT)) < 0) ERR;
      if (H5DSset_scale(lon_dimscaleid, NULL) < 0) ERR;
      if ((time_dimscaleid = H5Dcreate1(fileid, TIME_NAME, H5T_NATIVE_INT,
				      time_spaceid, H5P_DEFAULT)) < 0) ERR;
      if (H5DSset_scale(time_dimscaleid, NULL) < 0) ERR;
      if ((len_dimscaleid = H5Dcreate1(fileid, LEN_NAME, H5T_NATIVE_INT,
				      len_spaceid, H5P_DEFAULT)) < 0) ERR;
      if (H5DSset_scale(len_dimscaleid, NULL) < 0) ERR;

      /* Create a variable which uses these three dimscales. */
      if ((pres_datasetid = H5Dcreate1(fileid, PRES_NAME1, H5T_NATIVE_FLOAT,
				      pres_spaceid, H5P_DEFAULT)) < 0) ERR;
      if (H5DSattach_scale(pres_datasetid, lat_dimscaleid, 0) < 0) ERR;
      if (H5DSattach_scale(pres_datasetid, lon_dimscaleid, 1) < 0) ERR;
      if (H5DSattach_scale(pres_datasetid, time_dimscaleid, 2) < 0) ERR;

      /* Attach a dimscale to a dimscale. Unfortunately, HDF5 does not
       * allow this. Woe is me. */
      /*if (H5DSattach_scale(time_dimscaleid, len_dimscaleid, 0) < 0) ERR;*/

      /* Fold up our tents. */
      if (H5Dclose(lat_dimscaleid) < 0 ||
	  H5Dclose(lon_dimscaleid) < 0 ||
	  H5Dclose(time_dimscaleid) < 0 ||
	  H5Dclose(len_dimscaleid) < 0 ||
	  H5Dclose(pres_datasetid) < 0 ||
	  H5Sclose(lat_spaceid) < 0 ||
	  H5Sclose(lon_spaceid) < 0 ||
	  H5Sclose(time_spaceid) < 0 ||
	  H5Sclose(pres_spaceid) < 0 ||
	  H5Sclose(len_spaceid) < 0 ||
	  H5Pclose(fapl_id) < 0 ||
	  H5Pclose(fcpl_id) < 0 ||
	  H5Fclose(fileid) < 0) ERR;

      /* 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 = H5Dopen1(fileid, obj_name)) < 0) ERR;

	       /* Get space info. */
	       if ((spaceid = H5Dget_space(datasetid)) < 0) ERR;
	       if (H5Sget_simple_extent_dims(spaceid, dims, maxdims) < 0) ERR;
	       if ((ndims = H5Sget_simple_extent_ndims(spaceid)) < 0) ERR;

	       /* Is this a dimscale? */
	       if ((is_scale = H5DSis_scale(datasetid)) < 0) ERR;
	       if (is_scale)
	       {
		  /* fileno and objno uniquely identify an object and a
		   * HDF5 file. */
		  if (H5Gget_objinfo(datasetid, ".", 1, &statbuf) < 0) ERR;
		  dimscale_obj[dimscale_cnt].fileno[0] = statbuf.fileno[0];
		  dimscale_obj[dimscale_cnt].objno[0] = statbuf.objno[0];
		  dimscale_obj[dimscale_cnt].fileno[1] = statbuf.fileno[1];
		  dimscale_obj[dimscale_cnt].objno[1] = statbuf.objno[1];
		  /* printf("dimscale_obj[%d].fileno = %d dimscale_obj[%d].objno = %d\n", */
/* 			 dimscale_cnt, dimscale_obj[dimscale_cnt].fileno, dimscale_cnt, */
/* 			 dimscale_obj[dimscale_cnt].objno); */
		  dimscale_cnt++;
	       }
	       else
	       {
		  /* Here's how to get the number of scales attached
		   * to the dataset's dimension 0 and 1. */
		  if ((num_scales = H5DSget_num_scales(datasetid, 0)) < 0) ERR;
		  if (num_scales != 1) ERR;
		  if ((num_scales = H5DSget_num_scales(datasetid, 1)) < 0) ERR;
		  if (num_scales != 1) ERR;

		  /* Go through all dimscales for this var and learn about them. */
		  for (d = 0; d < ndims; d++)
		  {
		     if (H5DSiterate_scales(datasetid, d, NULL, alien_visitor2,
		     &(vars_dimscale_obj[d])) < 0) ERR;

		     /* Verify that the object ids passed from the
		      * alien_visitor2 function match the ones we found
		      * for the lat and lon datasets. */
		     if (vars_dimscale_obj[d].fileno[0] != dimscale_obj[d].fileno[0] ||
		     vars_dimscale_obj[d].objno[0] != dimscale_obj[d].objno[0]) ERR;
		     if (vars_dimscale_obj[d].fileno[1] != dimscale_obj[d].fileno[1] ||
		     vars_dimscale_obj[d].objno[1] != dimscale_obj[d].objno[1]) ERR;
		  }
	       }
	       if (H5Dclose(datasetid) < 0) ERR;
	       if (H5Sclose(spaceid) < 0) ERR;
	       break;
	    case H5G_TYPE:
	       break;
	    case H5G_LINK:
	       break;
	    default:
	       printf("Unknown object class %d!", obj_class);
	 }
      }

      /* Close up the shop. */
      if (H5Fclose(fileid) < 0) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** Checking cration ordering of datasets which are also dimension scales...");
   
   {
#define LAT_LEN 3
#define LON_LEN 2
#define TIME_LEN 5
#define LEN_LEN 10
#define DIMS_3 3
#define NUM_DIMSCALES2 4
#define LAT_NAME "lat"
#define LON_NAME "lon"
#define PRES_NAME1 "z_pres"
#define TIME_NAME "time"
#define LEN_NAME "u_len"
      
      hid_t fileid, lat_spaceid, lon_spaceid, time_spaceid, pres_spaceid, len_spaceid;
      hid_t pres_datasetid, lat_dimscaleid, lon_dimscaleid, time_dimscaleid, len_dimscaleid;
      hid_t fapl_id, fcpl_id;
      hsize_t dims[DIMS_3];
      hid_t spaceid = 0, datasetid = 0;
      hsize_t num_obj, i;
      int obj_class;
      char obj_name[NC_MAX_NAME + 1];
      htri_t is_scale;
      int num_scales;
      hsize_t maxdims[DIMS_3];
      H5G_stat_t statbuf;
      HDF5_OBJID_T dimscale_obj[NUM_DIMSCALES2], vars_dimscale_obj[NUM_DIMSCALES2];
      int dimscale_cnt = 0;
      int d, ndims;

      /* Create file access and create property lists. */
      if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR;
      if ((fcpl_id = H5Pcreate(H5P_FILE_CREATE)) < 0) ERR;
      
      /* Set latest_format in access propertly list. This ensures that
       * the latest, greatest, HDF5 versions are used in the file. */
      if (H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) ERR;

      /* Set H5P_CRT_ORDER_TRACKED in the creation property list. This
       * turns on HDF5 creation ordering in the file. */
      if (H5Pset_link_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED |
					       H5P_CRT_ORDER_INDEXED)) < 0) ERR;
      if (H5Pset_attr_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED |
					       H5P_CRT_ORDER_INDEXED)) < 0) ERR;

      /* Create file. */
      if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, fcpl_id, fapl_id)) < 0) ERR;

      /* Create the spaces that will be used for the dimscales. */
      dims[0] = LAT_LEN;
      if ((lat_spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR;
      dims[0] = LON_LEN;
      if ((lon_spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR;
      dims[0] = TIME_LEN;
      if ((time_spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR;
      dims[0] = LEN_LEN;
      if ((len_spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR;

      /* Create the space for the dataset. */
      dims[0] = LAT_LEN;
      dims[1] = LON_LEN;
      dims[2] = TIME_LEN;
      if ((pres_spaceid = H5Screate_simple(DIMS_3, dims, dims)) < 0) ERR;

      /* Create our dimension scales. */
      if ((lat_dimscaleid = H5Dcreate1(fileid, LAT_NAME, H5T_NATIVE_INT,
				      lat_spaceid, H5P_DEFAULT)) < 0) ERR;
      if (H5DSset_scale(lat_dimscaleid, NULL) < 0) ERR;
      if ((lon_dimscaleid = H5Dcreate1(fileid, LON_NAME, H5T_NATIVE_INT,
				      lon_spaceid, H5P_DEFAULT)) < 0) ERR;
      if (H5DSset_scale(lon_dimscaleid, NULL) < 0) ERR;
      if ((time_dimscaleid = H5Dcreate1(fileid, TIME_NAME, H5T_NATIVE_INT,
				      time_spaceid, H5P_DEFAULT)) < 0) ERR;
      if (H5DSset_scale(time_dimscaleid, NULL) < 0) ERR;
      if ((len_dimscaleid = H5Dcreate1(fileid, LEN_NAME, H5T_NATIVE_INT,
				      len_spaceid, H5P_DEFAULT)) < 0) ERR;
      if (H5DSset_scale(len_dimscaleid, NULL) < 0) ERR;

      /* Create a variable which uses these three dimscales. */
      if ((pres_datasetid = H5Dcreate1(fileid, PRES_NAME1, H5T_NATIVE_FLOAT,
				      pres_spaceid, H5P_DEFAULT)) < 0) ERR;
      if (H5DSattach_scale(pres_datasetid, lat_dimscaleid, 0) < 0) ERR;
      if (H5DSattach_scale(pres_datasetid, lon_dimscaleid, 1) < 0) ERR;
      if (H5DSattach_scale(pres_datasetid, time_dimscaleid, 2) < 0) ERR;

      /* Attach a dimscale to a dimscale. Unfortunately, HDF5 does not
       * allow this. Woe is me. */
      /*if (H5DSattach_scale(time_dimscaleid, len_dimscaleid, 0) < 0) ERR;*/

      /* Fold up our tents. */
      if (H5Dclose(lat_dimscaleid) < 0 ||
	  H5Dclose(lon_dimscaleid) < 0 ||
	  H5Dclose(time_dimscaleid) < 0 ||
	  H5Dclose(len_dimscaleid) < 0 ||
	  H5Dclose(pres_datasetid) < 0 ||
	  H5Sclose(lat_spaceid) < 0 ||
	  H5Sclose(lon_spaceid) < 0 ||
	  H5Sclose(time_spaceid) < 0 ||
	  H5Sclose(pres_spaceid) < 0 ||
	  H5Sclose(len_spaceid) < 0 ||
	  H5Pclose(fapl_id) < 0 ||
	  H5Pclose(fcpl_id) < 0 ||
	  H5Fclose(fileid) < 0) ERR;

      /* 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 = H5Dopen1(fileid, obj_name)) < 0) ERR;

	       /* Get space info. */
	       if ((spaceid = H5Dget_space(datasetid)) < 0) ERR;
	       if (H5Sget_simple_extent_dims(spaceid, dims, maxdims) < 0) ERR;
	       if ((ndims = H5Sget_simple_extent_ndims(spaceid)) < 0) ERR;

	       /* Is this a dimscale? */
	       if ((is_scale = H5DSis_scale(datasetid)) < 0) ERR;
	       if (is_scale)
	       {
		  /* fileno and objno uniquely identify an object and a
		   * HDF5 file. */
		  if (H5Gget_objinfo(datasetid, ".", 1, &statbuf) < 0) ERR;
		  dimscale_obj[dimscale_cnt].fileno[0] = statbuf.fileno[0];
		  dimscale_obj[dimscale_cnt].objno[0] = statbuf.objno[0];
		  dimscale_obj[dimscale_cnt].fileno[1] = statbuf.fileno[1];
		  dimscale_obj[dimscale_cnt].objno[1] = statbuf.objno[1];
		  /* printf("dimscale_obj[%d].fileno = %d dimscale_obj[%d].objno = %d\n", */
/* 			 dimscale_cnt, dimscale_obj[dimscale_cnt].fileno, dimscale_cnt, */
/* 			 dimscale_obj[dimscale_cnt].objno); */
		  dimscale_cnt++;
	       }
	       else
	       {
		  /* Here's how to get the number of scales attached
		   * to the dataset's dimension 0 and 1. */
		  if ((num_scales = H5DSget_num_scales(datasetid, 0)) < 0) ERR;
		  if (num_scales != 1) ERR;
		  if ((num_scales = H5DSget_num_scales(datasetid, 1)) < 0) ERR;
		  if (num_scales != 1) ERR;

		  /* Go through all dimscales for this var and learn about them. */
		  for (d = 0; d < ndims; d++)
		  {
		     if (H5DSiterate_scales(datasetid, d, NULL, alien_visitor2,
		     &(vars_dimscale_obj[d])) < 0) ERR;

		     /* Verify that the object ids passed from the
		      * alien_visitor2 function match the ones we found
		      * for the lat and lon datasets. */
		     if (vars_dimscale_obj[d].fileno[0] != dimscale_obj[d].fileno[0] ||
		     vars_dimscale_obj[d].objno[0] != dimscale_obj[d].objno[0]) ERR;
		     if (vars_dimscale_obj[d].fileno[1] != dimscale_obj[d].fileno[1] ||
		     vars_dimscale_obj[d].objno[1] != dimscale_obj[d].objno[1]) ERR;
		  }
	       }
	       if (H5Dclose(datasetid) < 0) ERR;
	       if (H5Sclose(spaceid) < 0) ERR;
	       break;
	    case H5G_TYPE:
	       break;
	    case H5G_LINK:
	       break;
	    default:
	       printf("Unknown object class %d!", obj_class);
	 }
      }

      /* Close up the shop. */
      if (H5Fclose(fileid) < 0) ERR;
   }

   SUMMARIZE_ERR;
   FINAL_RESULTS;
}
Пример #3
0
herr_t HDF5CreateGroupObjs(hid_t hHDF5, const char *pszObjName,
                           void *poHObjParent)
{
    hid_t       hGroupID;       /* identifier of group */
    hid_t       hDatasetID;     /* identifier of dataset */
    hsize_t     nbObjs=0;       /* number of objects in a group */
    int         nbAttrs=0;      /* number of attributes in object */
    unsigned    idx;
    int         n_dims;
    H5G_stat_t  oStatbuf;
    hsize_t     *dims=NULL;
    hsize_t     *maxdims=NULL;
    hid_t       datatype;
    hid_t       dataspace;
    hid_t       native;

    HDF5GroupObjects *poHchild;
    HDF5GroupObjects *poHparent;

    poHparent = ( HDF5GroupObjects * ) poHObjParent;
    poHchild=poHparent->poHchild;

    if( H5Gget_objinfo( hHDF5, pszObjName, FALSE, &oStatbuf ) < 0  )
        return -1;


/* -------------------------------------------------------------------- */
/*      Look for next child                                             */
/* -------------------------------------------------------------------- */
    for( idx=0; idx < poHparent->nbObjs; idx++ ) {
        if( poHchild->pszName == NULL ) break;
        poHchild++;
    }

    if( idx == poHparent->nbObjs )
        return -1;  // all children parsed

/* -------------------------------------------------------------------- */
/*      Save child information                                          */
/* -------------------------------------------------------------------- */
    poHchild->pszName  = CPLStrdup( pszObjName );

    poHchild->nType  = oStatbuf.type;
    poHchild->nIndex = idx;
    poHchild->poHparent = poHparent;
    poHchild->nRank     = 0;
    poHchild->paDims    = 0;
    poHchild->HDatatype = 0;
    poHchild->objno[0]  = oStatbuf.objno[0];
    poHchild->objno[1]  = oStatbuf.objno[1];
    if( poHchild->pszPath == NULL ) {
        poHchild->pszPath  = CreatePath( poHchild );
    }
    if( poHparent->pszPath == NULL ) {
        poHparent->pszPath = CreatePath( poHparent );
    }


    switch ( oStatbuf.type )
    {
        case H5G_LINK:
            poHchild->nbAttrs = 0;
            poHchild->nbObjs = 0;
            poHchild->poHchild = NULL;
            poHchild->nRank      = 0;
            poHchild->paDims    = 0;
            poHchild->HDatatype = 0;
            break;

        case H5G_GROUP:
            if( ( hGroupID = H5Gopen( hHDF5, pszObjName ) ) == -1  ) {
                printf( "Error: unable to access \"%s\" group.\n",
                        pszObjName );
                return -1;
            }
            nbAttrs          = H5Aget_num_attrs( hGroupID );
            H5Gget_num_objs( hGroupID, &nbObjs );
            poHchild->nbAttrs= nbAttrs;
            poHchild->nbObjs = (int) nbObjs;
            poHchild->nRank      = 0;
            poHchild->paDims    = 0;
            poHchild->HDatatype = 0;

            if( nbObjs > 0 ) {
                poHchild->poHchild =( HDF5GroupObjects * )
                CPLCalloc( (int)nbObjs, sizeof( HDF5GroupObjects ) );
                memset( poHchild->poHchild, 0,
                        (size_t) (sizeof( HDF5GroupObjects ) * nbObjs) );
            }
            else
                poHchild->poHchild = NULL;

            if( !HDF5GroupCheckDuplicate( poHparent, oStatbuf.objno ) )
                H5Giterate( hHDF5, pszObjName, NULL,
                            HDF5CreateGroupObjs,  (void*) poHchild );
            else
                CPLDebug( "HDF5", "avoiding link looping on node '%s'.",
                        pszObjName );

            H5Gclose( hGroupID );
            break;

        case H5G_DATASET:

            if( ( hDatasetID = H5Dopen( hHDF5, pszObjName ) ) == -1  ) {
                printf( "Error: unable to access \"%s\" dataset.\n",
                        pszObjName );
                return -1;
            }
            nbAttrs      = H5Aget_num_attrs( hDatasetID );
            datatype     = H5Dget_type( hDatasetID );
            dataspace    = H5Dget_space( hDatasetID );
            n_dims       = H5Sget_simple_extent_ndims( dataspace );
            native       = H5Tget_native_type( datatype, H5T_DIR_ASCEND );

            if( n_dims > 0 ) {
                dims     = (hsize_t *) CPLCalloc( n_dims,sizeof( hsize_t ) );
                maxdims  = (hsize_t *) CPLCalloc( n_dims,sizeof( hsize_t ) );
            }
            H5Sget_simple_extent_dims( dataspace, dims, maxdims );
            if( maxdims != NULL )
                CPLFree( maxdims );

            if( n_dims > 0 ) {
                poHchild->nRank     = n_dims;   // rank of the array
                poHchild->paDims    = dims;      // dimmension of the array.
                poHchild->HDatatype = datatype;  // HDF5 datatype
            }
            else  {
                poHchild->nRank     = -1;
                poHchild->paDims    = NULL;
                poHchild->HDatatype = 0;
            }
            poHchild->nbAttrs   = nbAttrs;
            poHchild->nbObjs    = 0;
            poHchild->poHchild  = NULL;
            poHchild->native    = native;
            H5Tclose( datatype );
            H5Sclose( dataspace );
            H5Dclose( hDatasetID );
            break;

        case H5G_TYPE:
            poHchild->nbAttrs = 0;
            poHchild->nbObjs = 0;
            poHchild->poHchild = NULL;
            poHchild->nRank      = 0;
            poHchild->paDims    = 0;
            poHchild->HDatatype = 0;
            break;

        default:
            break;
    }

    return 0;
}
Пример #4
0
/* ****************************************************************************************************************************** */
int main(int argc, char *argv[]) {
  hid_t   fileID, dataSetID;
  herr_t  hErrVal;
  int     i;
  hsize_t dims[1024], maxDims[1024];
  H5T_class_t class;
  char classStr[32];
  hid_t dataTypeID;
  size_t dataSize;
  H5T_order_t order;
  int rank; /* Note this is an int, not an hssize_t */
  int intVal;
  hid_t dataSpaceID;
  hid_t rootGroupID;
  hsize_t numInRootGrp, firstDataSetIdx, foundFirstDataSet;
  char attrName[1024], firstDataSetName[1024];
  ssize_t objectNameSize, attrNameSize;
  H5G_stat_t objectStatInfo;
  int numAttrs;
  int curAttrIdx;
  hid_t attrID;
  hsize_t numDataPoints;
  unsigned majnum, minnum, relnum;

  /* Load the library -- not required most platforms. */
  hErrVal = H5open();
  mjrHDF5_chkError(hErrVal);

  /* Get the library version */
  hErrVal = H5get_libversion(&majnum, &minnum, &relnum);
  mjrHDF5_chkError(hErrVal);
  printf("Lib Version: v%lu.%lur%lu\n", (unsigned long)majnum, (unsigned long)minnum, (unsigned long)relnum);

  /*  Open an existing file. */
  fileID = H5Fopen(TST_FILE_NAME, H5F_ACC_RDWR, H5P_DEFAULT);
  mjrHDF5_chkError(fileID);

  /*  Get the ID for the "root" group -- every HDF5 has one */
  rootGroupID = H5Gopen(fileID, "/", H5P_DEFAULT);
  mjrHDF5_chkError(rootGroupID);

  /* Get the number of objects in the root group. */
  hErrVal = H5Gget_num_objs(rootGroupID, &numInRootGrp);
  mjrHDF5_chkError(hErrVal);

  printf("The root group contains %lu object%c\n", (unsigned long)numInRootGrp, (numInRootGrp==1?' ':'s'));

  if(numInRootGrp < 1) {
    printf("As the file contains NO objects, I have nothing left to do...\n");
    exit(1);
  } /* end if */

  /*  Find the first dataset in the root group. */
  for(foundFirstDataSet=0,firstDataSetIdx=0; (!foundFirstDataSet)&&(firstDataSetIdx<numInRootGrp); firstDataSetIdx++) {
    /* Get object name from the index. */
    objectNameSize = H5Gget_objname_by_idx(rootGroupID, firstDataSetIdx, firstDataSetName, 1024);
    mjrHDF5_chkError(objectNameSize);
    if(objectNameSize == 0) { /* Need to check for zero return too */
      printf("ERROR: Object with index %lu doesn't exist in root group!\n", (unsigned long)firstDataSetIdx);
      exit(1);
    } /* end if */
    /*  Now use the object name to get info about the object... */
    hErrVal = H5Gget_objinfo(rootGroupID, firstDataSetName, 0, &objectStatInfo);
    mjrHDF5_chkError(hErrVal);
    /* If the object is a dataset, then print out some info. */
    if(objectStatInfo.type == H5G_DATASET) {
      printf("Object %luth (%s) is a dataset!\n", (unsigned long)firstDataSetIdx, firstDataSetName);
      printf("The name of the %luth object of the root group is: %s\n", (unsigned long)firstDataSetIdx, firstDataSetName);
      foundFirstDataSet = 1;
      printf("Info for the %s dataset:\n", firstDataSetName);
      printf("  Modify time: %lu\n", (unsigned long)objectStatInfo.mtime);
      printf("  Type: %lu\n", (unsigned long)objectStatInfo.type);
      printf("  Link count: %lu\n", (unsigned long)objectStatInfo.nlink);
    } /* end if */
  } /* end for */
  /* Note: At this point index of the dataset will be: firstDataSetIdx-- */
  if(!foundFirstDataSet) {
    printf("ERROR: Could not find a dataset in the root group\n");
    exit(1);
  } /* end if */

  /* Open the dataset we found -- we know it exists. */
  dataSetID = H5Dopen(rootGroupID, firstDataSetName, H5P_DEFAULT);
  mjrHDF5_chkError(dataSetID);

  /* ****************************************************************************************************************************** */
  /* Get some info regarding the TYPE of the dataset. */
  dataTypeID  = H5Dget_type(dataSetID);
  mjrHDF5_chkError(dataTypeID);
  /*  Get the class of the data */
  class = H5Tget_class(dataTypeID);
  mjrHDF5_Tclass2str(class, classStr);
  printf("  Object class: %s\n", classStr);
  /*  Get the size of the type */
  dataSize = H5Tget_size(dataTypeID);
  if(dataSize == 0) {
    printf("ERROR: Failure in H5Tget_size().\n");
    exit(1);
  } /* end if */
  printf("  Size of data type: %lu\n", (unsigned long)dataSize);
  /*  Get the byte order */
  order = H5Tget_order(dataTypeID);
  printf("  Byte Order: ");
  switch(order) {
    case H5T_ORDER_ERROR  : printf("ERROR\n");            break;
    case H5T_ORDER_LE     : printf("Little Endian\n");    break;
    case H5T_ORDER_BE     : printf("Big Endian\n");       break;
    case H5T_ORDER_VAX    : printf("VAX mixed endian\n"); break;
    case H5T_ORDER_MIXED  : printf("Mixed endian\n"); break;
    case H5T_ORDER_NONE   : printf("particular order\n"); break;
  } /* end switch */
  /*  We are done with the datatype. */
  hErrVal = H5Tclose(dataTypeID);
  mjrHDF5_chkError(hErrVal);

  /* ****************************************************************************************************************************** */
  /* Figure out the size of the dataset. */
  dataSpaceID = H5Dget_space(dataSetID);
  mjrHDF5_chkError(dataSpaceID);
  /*  Get the number of dims. */
  rank = H5Sget_simple_extent_ndims(dataSpaceID);
  mjrHDF5_chkError(rank);
  if(rank > 1024) {
    /*  This can't really happen (limit is 32) */
    printf("ERROR: rank too large.\n");
    exit(1);
  } /* end if */
  /* Get the size of each dim. */
  intVal = H5Sget_simple_extent_dims(dataSpaceID, dims, maxDims);
  mjrHDF5_chkError(intVal);
  printf("  Dataspace Rank %lu\n", (unsigned long)rank);
  printf("  Dim Lengths: ");
  for(i=0; i<rank; i++)
    if(dims[i] == H5S_UNLIMITED) {
      printf("%s ", "UNLIMITED");
    } else {
      printf("%ld ", (long)(dims[i]));
    } /* end if/else */
  printf("\n");
  printf("  Max Dim Lengths: ");
  for(i=0; i<rank; i++)
    if(maxDims[i] == H5S_UNLIMITED) {
      printf("%s ", "UNLIMITED");
    } else {
      printf("%ld ", (long)(maxDims[i]));
    } /* end if/else */
  printf("\n");
  numDataPoints = H5Sget_simple_extent_npoints(dataSpaceID);
  if(numDataPoints == 0) {
    printf("ERROR: Call to H5Sget_simple_extent_npoints failed.\n");
    exit(1);
  } /* end if */
  printf("Number of data points: %lu\n", (unsigned long)numDataPoints);

  /* We are done with the dataSpaceID */
  hErrVal = H5Sclose(dataSpaceID);
  mjrHDF5_chkError(hErrVal);

  /* Get the number of attributes for the dataSet. */
  numAttrs = H5Aget_num_attrs(dataSetID);
  mjrHDF5_chkError(numAttrs);

  printf("  Number of attrs: %lu\n", (unsigned long)numAttrs);

  /* If we have any attributes, we get info for them */
  if(numAttrs > 0) {
    printf("  Attribute info:\n");

    for(curAttrIdx=0; curAttrIdx<numAttrs; curAttrIdx++) {
      attrID = H5Aopen_idx(dataSetID, curAttrIdx);
      mjrHDF5_chkError(attrID);

      attrNameSize = H5Aget_name(attrID, 1024, attrName);
      mjrHDF5_chkError(attrNameSize);

      printf("    Number %3lu:  ", (unsigned long)curAttrIdx);

	  dataTypeID  = H5Aget_type(attrID);
	  mjrHDF5_chkError(dataTypeID);
	  /* Get the class for the type. */
	  class = H5Tget_class(dataTypeID);
	  mjrHDF5_Tclass2str(class, classStr);
	  printf(" Class: %-16s", classStr);
	  /*  Get the size of the type */
	  dataSize = H5Tget_size(dataTypeID);
	  if(dataSize == 0) {
		printf("ERROR: Failure in H5Tget_size().\n");
		exit(1);
	  } /* end if */
	  printf(" Size: %3lu ", (unsigned long)dataSize);
	  hErrVal = H5Tclose(dataTypeID);
	  mjrHDF5_chkError(hErrVal);

      printf(" Name: %s \n", attrName);

      hErrVal = H5Aclose(attrID);
	  mjrHDF5_chkError(hErrVal);
    } /* end for */
  } /* end if */