void SalomeIO::FindDimension(hid_t gid, const std::string menu_name, hsize_t n_fem_type) { Mesh& mesh = GetMesh(); uint mydim = 1; //this is the initial value, then it will be updated below mesh.SetDimension(mydim); std::vector<char*> elem_list; elem_list.resize(n_fem_type); for (unsigned j=0; j < elem_list.size(); j++) { elem_list[j] = new char[max_length]; H5Gget_objname_by_idx(gid,j,elem_list[j],max_length); ///@deprecated see the HDF doc to replace this std::string tempj(elem_list[j]); if ( tempj.compare("HE8") == 0 || tempj.compare("H20") == 0 || tempj.compare("H27") == 0 || tempj.compare("TE4") == 0 || tempj.compare("T10") == 0 ) { mydim = 3; } else if ( tempj.compare("QU4") == 0 || tempj.compare("QU8") == 0 || tempj.compare("QU9") == 0 || tempj.compare("TR3") == 0 || tempj.compare("TR6") == 0 ) { mydim = 2; } if ( mydim > mesh.GetDimension() ) mesh.SetDimension(mydim); } //end for return; }
int main() { printf("\n*** Checking HDF5 file c0.nc.\n"); printf("*** Checking HDF5 objcts..."); { hid_t fileid, grpid; hsize_t num_obj, i; char obj_name[MAX_NAME]; if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) ERR; if ((grpid = H5Gopen(fileid, "/")) < 0) ERR; /* Find the variables. Read their metadata and attributes. */ if (H5Gget_num_objs(grpid, &num_obj) < 0) ERR; for (i=0; i<num_obj; i++) { /* Get the class (i.e. group, dataset, etc.), and the name of * the object. */ if (H5Gget_objtype_by_idx(grpid, i) < 0) ERR; if (H5Gget_objname_by_idx(grpid, i, obj_name, MAX_NAME) < 0) ERR; } if (H5Gclose(grpid) < 0 || H5Fclose(fileid) < 0) ERR; } SUMMARIZE_ERR; FINAL_RESULTS; }
std::string HBase::getChildName(hsize_t i) { char memb_name[1024]; H5Gget_objname_by_idx(fObjectId, (hsize_t)i, memb_name, (size_t)1024 ); std::stringstream sst; sst.str(""); sst<<memb_name; return sst.str(); }
H5Object & H5LinksList::getObject(const int pos, const bool checkPos) { if (checkPos) { unsigned int size = getSize(); if (pos < 0 || pos >= size) { throw H5Exception(__LINE__, __FILE__, _("Invalid index %d: must be between 0 and %d."), pos, size); } } H5Object * obj = 0; hid_t parentId = getParent().getH5Id(); ssize_t nameSize = H5Gget_objname_by_idx(parentId, (hsize_t)pos, 0, 0); char * name = (char *)MALLOC((nameSize + 1) * sizeof(char)); H5Gget_objname_by_idx(parentId, (hsize_t)pos, name, nameSize + 1); int type = H5Gget_objtype_by_idx(parentId, (hsize_t)pos); switch (type) { case H5G_LINK: obj = &H5Link::getLink(getParent(), name); break; case H5G_GROUP: obj = new H5Group(getParent(), name); break; case H5G_DATASET: obj = new H5Dataset(getParent(), name); break; case H5G_TYPE: obj = new H5Type(getParent(), name); break; } return *obj; }
int AMRreader:: getInfo( const char* filename ) { debug2 << "opening AMR file " << filename << "\n"; filename_ = filename; hid_t file_id = H5Fopen( filename, H5F_ACC_RDONLY, H5P_DEFAULT ); if( file_id<0 ) { debug1 << "Failed to open AMR file: " << filename << ".\n"; return -1; } hsize_t nobjs; herr_t err = H5Gget_num_objs( file_id, &nobjs ); debug2 << "nobjs in " << filename << " is " << nobjs << "\n"; for( hsize_t i=0; i<nobjs; i++ ) { int type = H5Gget_objtype_by_idx( file_id, i ); if( type == H5G_GROUP ) { char name[1000]; ssize_t l= H5Gget_objname_by_idx( file_id, i, name, 1000 ); hid_t gid = H5Gopen1( file_id, name ); if( strcmp( name, amr_grpname )==0 ) { if( getAMRinfo( gid )!=0 ) { debug1 << "Failed to retrieve AMR info in " << filename << "\n"; H5Gclose(gid); return -2; }} else if( strcmp( name, intf_grp_name )==0 ) { if( getIntfInfo( gid ) != 0 ) { debug1 << "Failed to retrieve Interface info in " << filename << "\n"; return -3; }} else { debug1 << "Find a unrecongnized group " << name << " in " << filename << "\n"; } H5Gclose(gid); } } H5Fclose( file_id ); return 0; }
std::vector<std::string> HdfGroup::objects( H5G_obj_t type ) const { std::vector<std::string> lst; hsize_t nobj; H5Gget_num_objs( d->id, &nobj ); for ( hsize_t i = 0; i < nobj; ++i ) { if ( type == H5G_UNKNOWN || H5Gget_objtype_by_idx( d->id, i ) == type ) { char name[HDF_MAX_NAME]; H5Gget_objname_by_idx( d->id, i, name, ( size_t )HDF_MAX_NAME ); lst.push_back( std::string( name ) ); } } return lst; }
//------------------------------------------------------------------------------ // Description: // Finds the block index (blockIndx) within the HDF5 file associated with // the given file index. static bool FindBlockIndex(hid_t fileIndx, const int blockIdx, hid_t &rootIndx) { // retrieve the contents of the root directory to look for a group // corresponding to the target block, if available, open that group hsize_t numbObjs; rootIndx = H5Gopen(fileIndx, "/"); if (rootIndx < 0) { vtkGenericWarningMacro("Failed to open root node of particles file"); return false; } bool found = false; H5Gget_num_objs(rootIndx, &numbObjs); for (int objIndex = 0; objIndex < static_cast < int >(numbObjs); objIndex++) { if (H5Gget_objtype_by_idx(rootIndx, objIndex) == H5G_GROUP) { int blckIndx; char blckName[65]; H5Gget_objname_by_idx(rootIndx, objIndex, blckName, 64); // Is this the target block? if ((sscanf(blckName, "Grid%d", &blckIndx) == 1) && (blckIndx == blockIdx)) { // located the target block rootIndx = H5Gopen(rootIndx, blckName); if (rootIndx < 0) { vtkGenericWarningMacro("Could not locate target block!\n"); } found = true; break; } } // END if group } // END for all objects return (found); }
/* * utility function which checks whether a particular dataset * is present in the HDF5 file */ int checkfordataset(hid_t file_id, char *datasetname) { /* default is zero */ int ispresent=0; /* get number of datasets in file */ hsize_t ndatasets[1]; H5Gget_num_objs(file_id, ndatasets); /* loop over all datasets looking for dataset matching datasetname set function value to true (1) if it is present */ int i; char name[256]; for (i=0;i<(int)ndatasets[0];i++) { H5Gget_objname_by_idx(file_id, i, name, 256); /* printf(" dataset %s in file \n",name); */ if (strcmp(name,datasetname)==0) { /*printf(" %s in file \n",datasetname);*/ ispresent = 1; } } return ispresent; }
std::vector<std::string> hdf5file::subelements(const std::string& path, int desired_type) { hid_t group_id = H5Gopen(_file_id, path.c_str(), H5P_DEFAULT); const size_t MAX_NAME = 256; char element_name[MAX_NAME]; hsize_t object_count; H5Gget_num_objs(group_id, &object_count); std::vector<std::string> result; for(std::size_t i = 0; i < object_count; ++i) { int object_type = H5Gget_objtype_by_idx(group_id, i); H5Gget_objname_by_idx(group_id, i, element_name, MAX_NAME); if(object_type == desired_type) result.push_back(std::string(element_name)); } return result; }
/// @todo extend to Wegdes (aka Prisms) void SalomeIO::read(const std::string& name, vector < vector < double> > &coords, const double Lref, std::vector<bool> &type_elem_flag) { Mesh& mesh = GetMesh(); mesh.SetLevel(0); hsize_t dims[2]; // compute number of menus =============== hid_t file_id = H5Fopen(name.c_str(),H5F_ACC_RDWR, H5P_DEFAULT); hid_t gid = H5Gopen(file_id,mesh_ensemble.c_str(),H5P_DEFAULT); hsize_t n_menus; hid_t status= H5Gget_num_objs(gid, &n_menus); // number of menus if(status !=0) { std::cout << "Number of mesh menus not found"; abort(); } // compute number of groups and number of meshes =============== std::vector<std::string> mesh_menus; std::vector<std::string> group_menus; unsigned n_groups = 0; unsigned n_meshes = 0; for (unsigned j=0; j<n_menus; j++) { char * menu_names_j = new char[max_length]; H5Gget_objname_by_idx(gid,j,menu_names_j,max_length); ///@deprecated see the HDF doc to replace this std::string tempj(menu_names_j); if (tempj.substr(0,5).compare("Group") == 0) { n_groups++; group_menus.push_back(tempj); } else if (tempj.substr(0,4).compare("Mesh") == 0) { n_meshes++; mesh_menus.push_back(tempj); } } // compute number of groups and number of meshes =============== unsigned int n_elements_b_bb = 0; // meshes ======================== for (unsigned j=0; j< n_meshes; j++) { std::string tempj = mesh_menus[j]; // dimension =============== /// @todo this determination of the dimension from the mesh file would not work with a 2D mesh embedded in 3D std::string my_mesh_name_dir = mesh_ensemble + "/" + tempj + "/" + aux_zeroone + "/" + elem_list + "/"; ///@todo here we have to loop hsize_t n_fem_type; hid_t gid = H5Gopen(file_id,my_mesh_name_dir.c_str(),H5P_DEFAULT); hid_t status0 = H5Gget_num_objs(gid, &n_fem_type); if(status0 !=0) {std::cout << "SalomeIO::read_fem_type: H5Gget_num_objs not found"; abort();} FindDimension(gid,tempj,n_fem_type); H5Gclose(gid); if (mesh.GetDimension() != n_fem_type) { std::cout << "Mismatch between dimension and number of element types" << std::endl; abort(); } // fem type =============== std::vector<std::string> el_fe_type(mesh.GetDimension()); ReadFE(file_id,el_fe_type, n_fem_type, my_mesh_name_dir); // // read NODAL COORDINATES **************** C std::string coord_dataset = mesh_ensemble + "/" + tempj + "/" + aux_zeroone + "/" + node_list + "/" + coord_list + "/"; ///@todo here we have to loop hid_t dtset = H5Dopen(file_id,coord_dataset.c_str(),H5P_DEFAULT); // SET NUMBER OF NODES hid_t filespace = H5Dget_space(dtset); /* Get filespace handle first. */ hid_t status = H5Sget_simple_extent_dims(filespace, dims, NULL); if(status ==0) std::cerr << "SalomeIO::read dims not found"; // reading xyz_med unsigned int n_nodes = dims[0]/mesh.GetDimension(); double *xyz_med = new double[dims[0]]; std::cout << " Number of nodes in med file " << n_nodes << " " << std::endl; mesh.SetNumberOfNodes(n_nodes); // SET NODE COORDINATES coords[0].resize(n_nodes); coords[1].resize(n_nodes); coords[2].resize(n_nodes); status=H5Dread(dtset,H5T_NATIVE_DOUBLE,H5S_ALL,H5S_ALL,H5P_DEFAULT,xyz_med); H5Dclose(dtset); if (mesh.GetDimension()==3) { for (unsigned j=0; j<n_nodes; j++) { coords[0][j] = xyz_med[j]/Lref; coords[1][j] = xyz_med[j+n_nodes]/Lref; coords[2][j] = xyz_med[j+2*n_nodes]/Lref; } } else if (mesh.GetDimension()==2) { for (unsigned j=0; j<n_nodes; j++) { coords[0][j] = xyz_med[j]/Lref; coords[1][j] = xyz_med[j+n_nodes]/Lref; coords[2][j] = 0.; } } else if (mesh.GetDimension()==1) { for (unsigned j=0; j<n_nodes; j++) { coords[0][j] = xyz_med[j]/Lref; coords[1][j] = 0.; coords[2][j] = 0.; } } delete[] xyz_med; // // end read NODAL COORDINATES ************* C // // read ELEMENT/cell ******************** B std::string node_name_dir = my_mesh_name_dir + el_fe_type[mesh.GetDimension()-1] + "/" + connectivity; hid_t dtset2 = H5Dopen(file_id,node_name_dir.c_str(),H5P_DEFAULT); filespace = H5Dget_space(dtset2); status = H5Sget_simple_extent_dims(filespace, dims, NULL); if(status ==0) {std::cerr << "SalomeIO::read dims not found"; abort();} // DETERMINE NUMBER OF NODES PER ELEMENT unsigned Node_el = FindElemNodes( el_fe_type[mesh.GetDimension()-1] ); const int dim_conn = dims[0]; unsigned int n_elements = dim_conn/Node_el; // SET NUMBER OF ELEMENTS mesh.SetNumberOfElements(n_elements); int * conn_map = new int[dim_conn]; std::cout << " Number of elements in med file " << n_elements << std::endl; status=H5Dread(dtset2,H5T_NATIVE_INT,H5S_ALL,H5S_ALL,H5P_DEFAULT,conn_map); if(status !=0) {std::cout << "SalomeIO::read: connectivity not found"; abort();} H5Dclose(dtset2); mesh.el = new elem(n_elements); ///@todo check where this is going to be deleted // BOUNDARY (and BOUNDARY of the BOUNDARY in 3D) ========================= for (unsigned i=0; i < mesh.GetDimension()-1; i++) { hsize_t dims_i[2]; std::string node_name_dir_i = my_mesh_name_dir + el_fe_type[i] + "/" + dofobj_indices; hid_t dtset_i = H5Dopen(file_id,node_name_dir_i.c_str(),H5P_DEFAULT); filespace = H5Dget_space(dtset_i); hid_t status = H5Sget_simple_extent_dims(filespace, dims_i, NULL); if(status ==0) { std::cerr << "SalomeIO::read dims not found"; abort(); } n_elements_b_bb += dims_i[0]; H5Dclose(dtset_i); } // BOUNDARY ========================= for (unsigned iel=0; iel<n_elements; iel++) { mesh.el->SetElementGroup(iel,1); unsigned nve = Node_el; /// @todo this is only one element type if (nve==27) { type_elem_flag[0]=type_elem_flag[3]=true; mesh.el->AddToElementNumber(1,"Hex"); mesh.el->SetElementType(iel,HEX); } else if (nve==10) { type_elem_flag[1]=type_elem_flag[4]=true; mesh.el->AddToElementNumber(1,"Tet"); mesh.el->SetElementType(iel,TET); } else if (nve==18) { type_elem_flag[2]=type_elem_flag[3]=type_elem_flag[4]=true; mesh.el->AddToElementNumber(1,"Wedge"); mesh.el->SetElementType(iel,WEDGE); } else if (nve==9) { type_elem_flag[3]=true; mesh.el->AddToElementNumber(1,"Quad"); mesh.el->SetElementType(iel,QUAD); } else if (nve==6 && mesh.GetDimension()==2) { type_elem_flag[4]=true; mesh.el->AddToElementNumber(1,"Triangle"); mesh.el->SetElementType(iel,TRI); } else if (nve==3 && mesh.GetDimension()==1) { mesh.el->AddToElementNumber(1,"Line"); mesh.el->SetElementType(iel,LINE); } else { std::cout<<"Error! Invalid element type in reading File!"<<std::endl; std::cout<<"Error! Use a second order discretization"<<std::endl; exit(0); } for (unsigned i=0; i<nve; i++) { unsigned inode = SalomeToFemusVertexIndex[mesh.el->GetElementType(iel)][i]; mesh.el->SetElementVertexIndex(iel,inode,conn_map[iel+i*n_elements]); } } // // end read ELEMENT/CELL **************** B // clean delete [] conn_map; } //end meshes mesh.el->SetElementGroupNumber(n_groups); // read GROUP **************** E //we assume that these are VOLUME groups //in general, I'd say that a group can only have ONE element type (should study the possibility of hybrid mesh) for (unsigned j=0; j<n_groups; j++) { const uint n_fe_types_for_groups = 1; // so far we have this assumption std::string tempj = group_menus[j]; std::string my_mesh_name_dir = mesh_ensemble + "/" + tempj + "/" + aux_zeroone + "/" + elem_list + "/"; ///@todo here we have to loop /// @todo check the underscores according to our naming standard // strip the first number to get the group number // strip the second number to get the group material int gr_name = atoi(tempj.substr(6,1).c_str()); int gr_mat = atoi(tempj.substr(8,1).c_str()); std::vector<std::string> el_fe_type(mesh.GetDimension()); ReadFE(file_id, el_fe_type, n_fe_types_for_groups, my_mesh_name_dir); std::string group_dataset = mesh_ensemble + "/" + tempj + "/" + aux_zeroone + "/" + elem_list + "/" + el_fe_type[mesh.GetDimension()-1] + "/" + dofobj_indices; ///@todo here we have to loop hid_t dtset = H5Dopen(file_id,group_dataset.c_str(),H5P_DEFAULT); hid_t filespace = H5Dget_space(dtset); hid_t status = H5Sget_simple_extent_dims(filespace, dims, NULL); int * elem_indices = new int[dims[0]]; status=H5Dread(dtset,H5T_NATIVE_INT,H5S_ALL,H5S_ALL,H5P_DEFAULT,elem_indices); for (unsigned i=0; i < dims[0]; i++) { mesh.el->SetElementGroup(elem_indices[i] -1 - n_elements_b_bb, gr_name); mesh.el->SetElementMaterial(elem_indices[i] -1 - n_elements_b_bb ,gr_mat); } H5Dclose(dtset); delete [] elem_indices; } // // end read GROUP **************** E status = H5Fclose(file_id); //loop over volume elements //extract faces // // unsigned nbcd; // // read boundary **************** D // inf.open(name.c_str()); // if (!inf) { // std::cout<<"Generic-mesh file "<< name << " cannot read boudary\n"; // exit(0); // } // for (unsigned k=0; k<nbcd; k++) { // while (str2.compare("CONDITIONS") != 0) inf >> str2; // inf >> str2; // int value; // unsigned nface; // inf >>value>>str2>>nface>>str2>>str2; // value=-value-1; // for (unsigned i=0; i<nface; i++) { // unsigned iel,iface; // inf>>iel>>str2>>iface; // iel--; // iface=SalomeIO::SalomeToFemusFaceIndex[mesh.el->GetElementType(iel)][iface-1u]; // mesh.el->SetFaceElementIndex(iel,iface,value); // } // inf >> str2; // if (str2.compare("ENDOFSECTION") != 0) { // std::cout<<"error boundary data mesh"<<std::endl; // exit(0); // } // } // inf.close(); // // end read boundary **************** D }
void read_amuse_hdf5_data(char *filename, int maxtypes, int npartoftype[maxtypes], int ncol, int isrequired[ncol], int *ierr) { hid_t file_id; hid_t group_id, group_id1, group_id2; herr_t status; herr_t HDF5_error = -1; char groupname[12]; char datasetname[256]; int i; if (debug) printf("DEBUG: re-opening %s \n",filename); file_id = H5Fopen(filename,H5F_ACC_RDONLY,H5P_DEFAULT); if (file_id == HDF5_error) { printf("ERROR re-opening %s \n",filename); *ierr = 1; return; } /* open main particles group */ char *maingroup = "particles"; #if H5_VERSION_GE(1,8,0) group_id1 = H5Gopen2(file_id,maingroup,H5P_DEFAULT); #else group_id1 = H5Gopen(file_id,maingroup); #endif if (debug) printf("DEBUG: maxtypes = %i\n",maxtypes); /* read dataset for each particle type present in dump file */ int itype,iobjtype; for (itype=0;itype<maxtypes;itype++) { if (debug) printf("DEBUG: type %i npartoftype = %i\n",itype,npartoftype[itype]); if (npartoftype[itype] > 0) { /* If npartoftype[N] > 0 in header, look for dataset of the form 000000000N */ sprintf(groupname,"00000000%02i",itype+1); if (debug) printf("DEBUG: opening group %s\n",groupname); #if H5_VERSION_GE(1,8,0) group_id = H5Gopen2(group_id1,groupname,H5P_DEFAULT); #else group_id = H5Gopen(group_id1,groupname); #endif if (group_id == HDF5_error) { printf("ERROR opening %s group \n",groupname); *ierr = 2; } else { #if H5_VERSION_GE(1,8,0) group_id2 = H5Gopen2(group_id,"attributes",H5P_DEFAULT); #else group_id2 = H5Gopen(group_id,"attributes"); #endif if (group_id2 == HDF5_error) { printf("ERROR opening attributes group \n"); *ierr = 2; } else { hsize_t ndatasets; status = H5Gget_num_objs(group_id2, &ndatasets); if (debug) printf("DEBUG: number of datasets = %i \n",(int)ndatasets); int j = 0; /* always read particle positions first */ *ierr = read_amuse_hdf5_dataset(group_id2,"x",itype,maxtypes,npartoftype,ncol,isrequired,&j); j = 1; *ierr = read_amuse_hdf5_dataset(group_id2,"y",itype,maxtypes,npartoftype,ncol,isrequired,&j); j = 2; *ierr = read_amuse_hdf5_dataset(group_id2,"z",itype,maxtypes,npartoftype,ncol,isrequired,&j); /* read remaining datasets in the order they appear in the file */ for(i=0; i < (int)ndatasets; i++) { status = H5Gget_objname_by_idx(group_id2, i, datasetname, 256); iobjtype = H5Gget_objtype_by_idx(group_id2, i); if (strcmp(datasetname,"x")&& strcmp(datasetname,"y")&& strcmp(datasetname,"z")&& (iobjtype == H5G_DATASET)) { *ierr = read_amuse_hdf5_dataset(group_id2,datasetname,itype,maxtypes,npartoftype,ncol,isrequired,&j); } } /* close "attributes" group */ H5Gclose(group_id2); } H5Gclose(group_id); } } } H5Gclose(group_id1); status = H5Fclose( file_id ); if (status == HDF5_error) { printf("ERROR closing file \n"); *ierr = 7; } }
void rdiff(const char *name, hid_t f1, hid_t f2) { hid_t g1 = H5Gopen(f1, name, H5P_DEFAULT); hid_t g2 = H5Gopen(f2, name, H5P_DEFAULT); if (g1 >= 0 && g2 >= 0) { int n1 = H5Aget_num_attrs(g1); for (int i = 0; i < n1; i++) { char aname[MAXNAME]; hid_t a1 = H5Aopen_idx(g1, i); assert(H5Aget_name(a1, MAXNAME, aname) < MAXNAME); H5Aclose(a1); if (!H5LTfind_attribute(g2, aname)) { printf("Only in %s[%s%s]\n", file1, name, aname); continue; } int d1, d2; H5LTget_attribute_ndims(f1, name, aname, &d1); H5LTget_attribute_ndims(f2, name, aname, &d2); assert(d1 <= 1 && d2 <= 1); hsize_t dims1, dims2; H5T_class_t t1, t2; size_t ts1, ts2; H5LTget_attribute_info(f1, name, aname, &dims1, &t1, &ts1); H5LTget_attribute_info(f2, name, aname, &dims2, &t2, &ts2); assert(t1 == t2); assert(t1 == H5T_INTEGER || t1 == H5T_FLOAT || t1 == H5T_STRING); if (t1 == H5T_INTEGER) { assert(d1==0 || (dims1 == 1 && dims2 == 1)); assert(ts1 == 4 && ts2 == 4); int v1, v2; H5LTget_attribute_int(f1, name, aname, &v1); H5LTget_attribute_int(f2, name, aname, &v2); if (v1 != v2) { printf("%s[%s%s]=%d %s[%s%s]=%d\n", file1, name, aname, v1, file2, name, aname, v2); } } if (t1 == H5T_FLOAT) { assert(d1==0 || (dims1 == 1 && dims2 == 1)); assert(ts1 == 4 && ts2 == 4); float v1, v2; H5LTget_attribute_float(f1, name, aname, &v1); H5LTget_attribute_float(f2, name, aname, &v2); if (v1 != v2) { printf("%s[%s%s]=%g %s[%s%s]=%g\n", file1, name, aname, v1, file2, name, aname, v2); } } if (t1 == H5T_STRING) { assert(ts1 < 256 && ts2 < 256); char buf1[256]; char buf2[256]; H5LTget_attribute_string(f1, name, aname, buf1); H5LTget_attribute_string(f2, name, aname, buf2); if (strcmp(buf1, buf2)) { printf("%s[%s%s]=%s %s[%s%s]=%s\n", file1, name, aname, buf1, file2, name, aname, buf2); } } } int n2 = H5Aget_num_attrs(g2); for (int i = 0; i < n2; i++) { char aname[MAXNAME]; hid_t a2 = H5Aopen_idx(g2, i); assert(H5Aget_name(a2, MAXNAME, aname) < MAXNAME); H5Aclose(a2); if (!H5LTfind_attribute(g1, aname)) { printf("Only in %s[%s%s]\n", file2, name, aname); continue; } } hsize_t nobj; H5Gget_num_objs(g1, &nobj); for (int i = 0; i < nobj; i++) { char oname[MAXNAME]; assert(H5Gget_objname_by_idx(g1, i, oname, MAXNAME) < MAXNAME); int otype = H5Gget_objtype_by_idx(g1, i); assert(otype == H5G_DATASET); if (!H5LTfind_dataset(g2, oname)) { printf("Only in %s[%s%s]\n", file1, name, oname); continue; } hsize_t dims1[2], dims2[2]; H5T_class_t t1, t2; size_t ts1, ts2; H5LTget_dataset_info(g1, oname, dims1, &t1, &ts1); H5LTget_dataset_info(g2, oname, dims2, &t2, &ts2); if (dims1[0] != dims2[0] || dims1[1] != dims2[1]) { printf("%s[%s%s](%d,%d) != %s[%s%s](%d,%d)\n", file1, name, oname, dims1[1], dims1[0], file2, name, oname, dims2[1], dims2[0]); continue; } float *data1 = malloc(dims1[0]*dims1[1]*sizeof(float)); float *data2 = malloc(dims1[0]*dims1[1]*sizeof(float)); H5LTread_dataset_float(g1, oname, data1); H5LTread_dataset_float(g2, oname, data2); float maxdiff = 0; for (int i = dims1[0]*dims1[1]-1; i >= 0; i--) { float d = data1[i] - data2[i]; if (d < 0) d = -d; if (d > maxdiff) maxdiff = d; } printf("max |%s[%s%s] - %s[%s%s]| = %g\n", file1, name, oname, file2, name, oname, maxdiff); free(data1); free(data2); } H5Gget_num_objs(g2, &nobj); for (int i = 0; i < nobj; i++) { char oname[MAXNAME]; assert(H5Gget_objname_by_idx(g2, i, oname, MAXNAME) < MAXNAME); int otype = H5Gget_objtype_by_idx(g2, i); assert(otype == H5G_DATASET); if (!H5LTfind_dataset(g1, oname)) { printf("Only in %s[%s%s]\n", file2, name, oname); continue; } } H5Gclose(g1); H5Gclose(g2); } else if (g1 >= 0) { printf("Only in %s:%s\n", file1, name); H5Gclose(g1); } else if (g2 >= 0) { printf("Only in %s:%s\n", file2, name); H5Gclose(g2); } else { printf("Group %s does not exist in either file.\n", name); } }
int rec_scan_group(hid_t grpid) { hid_t spaceid, datasetid = 0, child_grpid; hsize_t num_obj, i; int obj_class; char obj_name[STR_LEN + 1]; htri_t is_scale; int num_scales; hsize_t dims[MAX_DIMS], max_dims[MAX_DIMS]; int ndims, d; /* Loop through datasets to find variables. */ 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, STR_LEN) < 0) ERR; /*printf("\nEncountered: HDF5 object obj_class %d obj_name %s\n", obj_class, obj_name);*/ /* Deal with groups and datasets, ignore the rest. */ switch(obj_class) { case H5G_GROUP: if ((child_grpid = H5Gopen(grpid, obj_name)) < 0) ERR; if (rec_scan_group(child_grpid)) ERR; break; case H5G_DATASET: /* Open the dataset. */ if ((datasetid = H5Dopen(grpid, obj_name)) < 0) ERR; /*printf("\nobj_name %s\n", obj_name);*/ /* Get the dimensions of this dataset. */ if ((spaceid = H5Dget_space(datasetid)) < 0) ERR; if ((ndims = H5Sget_simple_extent_ndims(spaceid)) < 0) ERR; if (ndims > MAX_DIMS) ERR; if (H5Sget_simple_extent_dims(spaceid, dims, max_dims) < 0) ERR; /* Is this a dimscale? */ if ((is_scale = H5DSis_scale(datasetid)) < 0) ERR; if (is_scale) { /*printf("dimension scale! Hoorah for the Pirate King!\n");*/ } else { int visitor_data = 0; /* 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. */ for (d = 0; d < ndims; d++) if (H5DSiterate_scales(datasetid, d, NULL, alien_visitor, &visitor_data) < 0) ERR; } if (H5Dclose(datasetid) < 0) ERR; break; case H5G_TYPE: printf("found a type!\n"); break; case H5G_LINK: printf("found a link! Yikes!\n"); break; default: printf("Unknown object class %d!", obj_class); } } return 0; }
int main() { printf("\n*** Checking HDF5 dimension scales.\n"); #define GRP_NAME "simple_scales" #define DIMSCALE_NAME "dimscale" #define NAME_ATTRIBUTE "Billy-Bob" #define VAR1_NAME "var1" #define VAR2_NAME "var2" #define VAR3_NAME "var3" #define DIM1_LEN 3 #define DIM2_LEN 2 #define FIFTIES_SONG "Mamma said they'll be days like this. They'll be days like this, my mamma said." printf("*** Creating simple dimension scales file..."); { hid_t fileid, grpid, dimscaleid; hid_t dimscale_spaceid, var1_spaceid, var3_spaceid; hid_t var1_datasetid, var2_datasetid, var3_datasetid; hsize_t dims[2] = {DIM1_LEN, DIM2_LEN}; hsize_t dimscale_dims[1] = {DIM1_LEN}; /* Open file and create group. */ if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR; if ((grpid = H5Gcreate(fileid, GRP_NAME, 0)) < 0) ERR; /* Create our dimension scale. Use the built-in NAME attribute * on the dimscale. */ if ((dimscale_spaceid = H5Screate_simple(1, dimscale_dims, dimscale_dims)) < 0) ERR; if ((dimscaleid = H5Dcreate(grpid, DIMSCALE_NAME, H5T_NATIVE_INT, dimscale_spaceid, H5P_DEFAULT)) < 0) ERR; if (H5DSset_scale(dimscaleid, NAME_ATTRIBUTE) < 0) ERR; /* Create a 1D variable which uses the dimscale. Attach a label * to this scale. */ if ((var1_spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR; if ((var1_datasetid = H5Dcreate(grpid, VAR1_NAME, H5T_NATIVE_INT, var1_spaceid, H5P_DEFAULT)) < 0) ERR; if (H5DSattach_scale(var1_datasetid, dimscaleid, 0) < 0) ERR; if (H5DSset_label(var1_datasetid, 0, FIFTIES_SONG) < 0) ERR; /* Create a 1D variabls that doesn't use the dimension scale. */ if ((var2_datasetid = H5Dcreate(grpid, VAR2_NAME, H5T_NATIVE_INT, var1_spaceid, H5P_DEFAULT)) < 0) ERR; /* Create a 2D dataset which uses the scale for one of its * dimensions. */ if ((var3_spaceid = H5Screate_simple(2, dims, dims)) < 0) ERR; if ((var3_datasetid = H5Dcreate(grpid, VAR3_NAME, H5T_NATIVE_INT, var3_spaceid, H5P_DEFAULT)) < 0) ERR; if (H5DSattach_scale(var3_datasetid, dimscaleid, 0) < 0) ERR; /* Close up the shop. */ if (H5Dclose(dimscaleid) < 0 || H5Dclose(var1_datasetid) < 0 || H5Dclose(var2_datasetid) < 0 || H5Dclose(var3_datasetid) < 0 || H5Sclose(var1_spaceid) < 0 || H5Sclose(var3_spaceid) < 0 || H5Sclose(dimscale_spaceid) < 0 || H5Gclose(grpid) < 0 || H5Fclose(fileid) < 0) ERR; /* HELP! If you are reading this in the future, and time * machines have been invented, please come back to July 10, * 2005, the Java Java coffee shop in Lafayette, 8:00 am MST +- * 20 minutes. Bring back some advanced weapons systems to * destroy the sound system here, which is playing 50's rock and * roll. Do-op, do-op, la-ma la-ma, ding dong. Save me!!! (Mind * you, James Brown is a different story!) */ } SUMMARIZE_ERR; printf("*** Checking that simple dimscale file can be read..."); { hid_t fileid, grpid, datasetid = 0; hsize_t num_obj, i; int obj_class; char obj_name[STR_LEN + 1]; htri_t is_scale; int num_scales; /* Reopen the file and group. */ if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) ERR; if ((grpid = H5Gopen(fileid, GRP_NAME)) < 0) ERR; /* Loop through datasets to find variables. */ 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. Confusingly, this is a different type than the type * of a variable. This type might be better called "class" or * "type of type" */ if ((obj_class = H5Gget_objtype_by_idx(grpid, i)) < 0) ERR; if (H5Gget_objname_by_idx(grpid, i, obj_name, STR_LEN) < 0) ERR; /*printf("\nEncountered: HDF5 object obj_class %d obj_name %s\n", obj_class, obj_name);*/ /* Deal with groups and datasets. */ switch(obj_class) { case H5G_GROUP: break; case H5G_DATASET: /*Close the last datasetid, if one is open. */ if (datasetid > 0) { H5Dclose(datasetid); } if ((datasetid = H5Dopen(grpid, obj_name)) < 0) ERR; if ((is_scale = H5DSis_scale(datasetid)) < 0) ERR; if (is_scale && strcmp(obj_name, DIMSCALE_NAME)) ERR; if (is_scale) { char nom_de_quincey[STR_LEN+1]; /* A dimscale comes with a NAME attribute, in * addition to its real name. */ if (H5DSget_scale_name(datasetid, nom_de_quincey, STR_LEN) < 0) ERR; if (strcmp(nom_de_quincey, NAME_ATTRIBUTE)) ERR; /*printf("found scale %s, NAME %s\n", obj_name, nom_de_quincey);*/ } else { char label[STR_LEN+1]; /* Here's how to get the number of scales attached * to the dataset. I would think that this would * return 0 scales for a dataset that doesn't have * scales, but instead it errors. So take an error * to be the same as no dimension scales. */ num_scales = H5DSget_num_scales(datasetid, 0); if (strcmp(obj_name, VAR1_NAME) == 0 && num_scales != 1) ERR; if (strcmp(obj_name, VAR2_NAME) == 0 && num_scales > 0) ERR; if (strcmp(obj_name, VAR3_NAME) == 0 && num_scales != 1) ERR; /* There's also a label for dimension 0 of var1. */ if (strcmp(obj_name, VAR1_NAME) == 0) { if (H5DSget_label(datasetid, 0, label, STR_LEN) < 0) ERR; if (strcmp(label, FIFTIES_SONG)) ERR; } } break; case H5G_TYPE: break; case H5G_LINK: break; default: printf("Unknown object class %d!", obj_class); } } /* Close up the shop. */ if (H5Dclose(datasetid) < 0 || H5Gclose(grpid) < 0 || H5Fclose(fileid) < 0) ERR; } SUMMARIZE_ERR; printf("*** Creating simple dimension scales file with lots of datasets..."); #define NUM_DATASETS 500 { hid_t fileid, grpid, dimscaleid; hid_t dimscale_spaceid, var1_spaceid; hid_t var1_datasetid[NUM_DATASETS]; hsize_t dims[2] = {DIM1_LEN, DIM2_LEN}; hsize_t dimscale_dims[1] = {DIM1_LEN}; char var_name[STR_LEN + 1]; int v; /* Open file and create group. */ if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR; if ((grpid = H5Gcreate(fileid, GRP_NAME, 0)) < 0) ERR; /* Create our dimension scale. Use the built-in NAME attribute * on the dimscale. */ if ((dimscale_spaceid = H5Screate_simple(1, dimscale_dims, dimscale_dims)) < 0) ERR; if ((dimscaleid = H5Dcreate(grpid, DIMSCALE_NAME, H5T_NATIVE_INT, dimscale_spaceid, H5P_DEFAULT)) < 0) ERR; if (H5DSset_scale(dimscaleid, NAME_ATTRIBUTE) < 0) ERR; /* Create many 1D datasets which use the dimscale. */ if ((var1_spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR; for (v = 0; v < NUM_DATASETS; v++) { sprintf(var_name, "var_%d", v); if ((var1_datasetid[v] = H5Dcreate(grpid, var_name, H5T_NATIVE_INT, var1_spaceid, H5P_DEFAULT)) < 0) ERR; if (H5DSattach_scale(var1_datasetid[v], dimscaleid, 0) < 0) ERR; } /* Close up the shop. */ for (v = 0; v < NUM_DATASETS; v++) if (H5Dclose(var1_datasetid[v]) < 0) ERR; if (H5Dclose(dimscaleid) < 0 || H5Sclose(var1_spaceid) < 0 || H5Sclose(dimscale_spaceid) < 0 || H5Gclose(grpid) < 0 || H5Fclose(fileid) < 0) ERR; } SUMMARIZE_ERR; printf("*** Creating a file with an unlimited dimension scale..."); { hid_t fileid, grpid, spaceid, datasetid, dimscaleid, cparmsid; hsize_t dims[1] = {1}, maxdims[1] = {H5S_UNLIMITED}; /* Create file and group. */ if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR; if ((grpid = H5Gcreate(fileid, GRP_NAME, 0)) < 0) ERR; if ((spaceid = H5Screate_simple(1, dims, maxdims)) < 0) ERR; /* Modify dataset creation properties, i.e. enable chunking */ if ((cparmsid = H5Pcreate(H5P_DATASET_CREATE)) < 0) ERR; if (H5Pset_chunk(cparmsid, 1, dims) < 0) ERR; /* Create our dimension scale, as an unlimited dataset. */ if ((dimscaleid = H5Dcreate(grpid, 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(grpid, VAR1_NAME, H5T_NATIVE_INT, spaceid, cparmsid)) < 0) ERR; if (H5DSattach_scale(datasetid, dimscaleid, 0) < 0) ERR; if (H5DSset_label(datasetid, 0, "dimension label") < 0) ERR; /* Close up the shop. */ if (H5Dclose(dimscaleid) < 0 || H5Dclose(datasetid) < 0 || H5Sclose(spaceid) < 0 || H5Gclose(grpid) < 0 || H5Fclose(fileid) < 0) ERR; } SUMMARIZE_ERR; #ifdef EXTRA_TESTS printf("*** Checking that unlimited dimscale file can be read..."); { hid_t fileid, grpid, spaceid = 0, datasetid = 0; hsize_t num_obj, i; int obj_class; char obj_name[STR_LEN + 1]; htri_t is_scale; int num_scales; hsize_t dims[1], maxdims[1]; /* Reopen the file and group. */ if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) ERR; if ((grpid = H5Gopen(fileid, GRP_NAME)) < 0) ERR; /* Loop through datasets to find variables. */ 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, STR_LEN) < 0) ERR; /*printf("\nEncountered: HDF5 object obj_class %d obj_name %s\n", obj_class, obj_name);*/ /* Deal with groups and datasets. */ switch(obj_class) { case H5G_GROUP: break; case H5G_DATASET: /*Close the last datasetid, if one is open. */ if (datasetid > 0) { H5Dclose(datasetid); datasetid = 0; } /* Open the dataset. */ if ((datasetid = H5Dopen(grpid, 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) { char nom_de_quincey[STR_LEN+1]; /* A dimscale comes with a NAME attribute, in * addition to its real name. */ if (H5DSget_scale_name(datasetid, nom_de_quincey, STR_LEN) < 0) ERR; /*printf("found scale %s, NAME %s\n", obj_name, nom_de_quincey);*/ } else { char label[STR_LEN+1]; int visitor_data = 0; /* 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, STR_LEN) < 0) ERR; /*printf("found non-scale dataset %s, label %s\n", obj_name, label);*/ } break; case H5G_TYPE: break; case H5G_LINK: break; default: printf("Unknown object class %d!", obj_class); } } /* Close up the shop. */ if (H5Dclose(datasetid) < 0 || H5Sclose(spaceid) < 0 || H5Gclose(grpid) < 0 || H5Fclose(fileid) < 0) ERR; } SUMMARIZE_ERR; printf("*** Creating some 3D datasets using shared dimscales..."); { #define NDIMS 3 #define TIME_DIM 0 #define LAT_DIM 1 #define LON_DIM 2 #define LAT_LEN 2 #define LON_LEN 3 #define LAT_NAME "Lat" #define LON_NAME "Lon" #define TIME_NAME "Time" #define PRES_NAME "Pressure" #define TEMP_NAME "Temperature" hid_t fileid, grpid, lat_spaceid, lon_spaceid, time_spaceid, spaceid; hid_t lat_scaleid, lon_scaleid, time_scaleid; hid_t pres_dsid, temp_dsid, cparmsid; hsize_t dims[NDIMS], max_dims[NDIMS]; /* Create file and group. */ if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR; if ((grpid = H5Gcreate(fileid, GRP_NAME, 0)) < 0) ERR; /* Create 3 1D spaces for the 3 dimension scale datasets. Time * starts out as size 0. It's an unlimited dimension scale. */ dims[0] = 0; max_dims[0] = H5S_UNLIMITED; if ((time_spaceid = H5Screate_simple(1, dims, max_dims)) < 0) ERR; dims[0] = LAT_LEN; max_dims[0] = LAT_LEN; if ((lat_spaceid = H5Screate_simple(1, dims, max_dims)) < 0) ERR; dims[0] = LON_LEN; max_dims[0] = LON_LEN; if ((lon_spaceid = H5Screate_simple(1, dims, max_dims)) < 0) ERR; /* Enable chunking for unlimited time scale. */ if ((cparmsid = H5Pcreate(H5P_DATASET_CREATE)) < 0) ERR; dims[TIME_DIM] = 1; if (H5Pset_chunk(cparmsid, 1, dims) < 0) ERR; /* Create our dimension scales. */ if ((time_scaleid = H5Dcreate(grpid, TIME_NAME, H5T_NATIVE_INT, time_spaceid, cparmsid)) < 0) ERR; if (H5DSset_scale(time_scaleid, TIME_NAME) < 0) ERR; if ((lat_scaleid = H5Dcreate(grpid, LAT_NAME, H5T_NATIVE_FLOAT, lat_spaceid, H5P_DEFAULT)) < 0) ERR; if (H5DSset_scale(lat_scaleid, LAT_NAME) < 0) ERR; if ((lon_scaleid = H5Dcreate(grpid, LON_NAME, H5T_NATIVE_FLOAT, lon_spaceid, H5P_DEFAULT)) < 0) ERR; if (H5DSset_scale(lon_scaleid, LON_NAME) < 0) ERR; /* Create a space coresponding to these three dimensions. */ dims[TIME_DIM] = 0; dims[LAT_DIM] = LAT_LEN; dims[LON_DIM] = LON_LEN; max_dims[TIME_DIM] = H5S_UNLIMITED; max_dims[LAT_DIM] = LAT_LEN; max_dims[LON_DIM] = LON_LEN; if ((spaceid = H5Screate_simple(NDIMS, dims, max_dims)) < 0) ERR; /* Create two variables which use them, and attach the dimension scales. */ dims[TIME_DIM] = 1; if (H5Pset_chunk(cparmsid, NDIMS, dims) < 0) ERR; if ((pres_dsid = H5Dcreate(grpid, PRES_NAME, H5T_NATIVE_FLOAT, spaceid, cparmsid)) < 0) ERR; if (H5DSattach_scale(pres_dsid, time_scaleid, 0) < 0) ERR; if (H5DSattach_scale(pres_dsid, lat_scaleid, 1) < 0) ERR; if (H5DSattach_scale(pres_dsid, lon_scaleid, 2) < 0) ERR; if (H5DSset_label(pres_dsid, TIME_DIM, TIME_NAME) < 0) ERR; if (H5DSset_label(pres_dsid, LAT_DIM, LAT_NAME) < 0) ERR; if (H5DSset_label(pres_dsid, LON_DIM, LON_NAME) < 0) ERR; if ((temp_dsid = H5Dcreate(grpid, TEMP_NAME, H5T_NATIVE_FLOAT, spaceid, cparmsid)) < 0) ERR; if (H5DSattach_scale(temp_dsid, time_scaleid, 0) < 0) ERR; if (H5DSattach_scale(temp_dsid, lat_scaleid, 1) < 0) ERR; if (H5DSattach_scale(temp_dsid, lon_scaleid, 2) < 0) ERR; if (H5DSset_label(temp_dsid, TIME_DIM, TIME_NAME) < 0) ERR; if (H5DSset_label(temp_dsid, LAT_DIM, LAT_NAME) < 0) ERR; if (H5DSset_label(temp_dsid, LON_DIM, LON_NAME) < 0) ERR; /* Close up the shop. */ if (H5Dclose(pres_dsid) < 0 || H5Dclose(temp_dsid) < 0 || H5Dclose(lat_scaleid) < 0 || H5Dclose(lon_scaleid) < 0 || H5Dclose(time_scaleid) < 0 || H5Sclose(spaceid) < 0 || H5Gclose(grpid) < 0 || H5Fclose(fileid) < 0) ERR; } SUMMARIZE_ERR; printf("*** Checking 3D datasets created with shared dimscales..."); { hid_t fileid, grpid, spaceid = 0, datasetid = 0; hsize_t num_obj, i; int obj_class; char obj_name[STR_LEN + 1]; htri_t is_scale; int num_scales; hsize_t dims[NDIMS], max_dims[NDIMS]; int d; /* Reopen the file and group. */ if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) ERR; if ((grpid = H5Gopen(fileid, GRP_NAME)) < 0) ERR; /* Loop through datasets to find variables. */ 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, STR_LEN) < 0) ERR; /*printf("\nEncountered: HDF5 object obj_class %d obj_name %s\n", obj_class, obj_name);*/ /* Deal with groups and datasets. */ switch(obj_class) { case H5G_GROUP: break; case H5G_DATASET: /* Open the dataset. */ if ((datasetid = H5Dopen(grpid, obj_name)) < 0) ERR; /*printf("\nobj_name %s\n", obj_name);*/ /* Get the dimensions of this dataset. */ if ((spaceid = H5Dget_space(datasetid)) < 0) ERR; if (H5Sget_simple_extent_dims(spaceid, dims, max_dims) < 0) ERR; /* Is this a dimscale? */ if ((is_scale = H5DSis_scale(datasetid)) < 0) ERR; if (is_scale) { char nom_de_quincey[STR_LEN+1]; /* A dimscale comes with a NAME attribute, in * addition to its real name. */ if (H5DSget_scale_name(datasetid, nom_de_quincey, STR_LEN) < 0) ERR; /*printf("found scale %s, NAME %s id 0x%x\n", obj_name, nom_de_quincey, datasetid);*/ /* Check size depending on name. */ if ((!strcmp(obj_name, LAT_NAME) && dims[TIME_DIM] != LAT_LEN) || (!strcmp(obj_name, LON_NAME) && dims[TIME_DIM] != LON_LEN) || (!strcmp(obj_name, TIME_NAME) && max_dims[TIME_DIM] != H5S_UNLIMITED)) ERR; } else { char label[STR_LEN+1]; int visitor_data = 0; /* SHould have these dimensions... */ if (dims[TIME_DIM] != 0 || dims[LAT_DIM] != LAT_LEN || dims[LON_DIM] != LON_LEN) ERR; if (max_dims[TIME_DIM] != H5S_UNLIMITED) ERR; /* 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. What I want is the dataset id of each * dimscale. Then... */ for (d = 0; d < NDIMS; d++) if (H5DSiterate_scales(datasetid, d, NULL, alien_visitor, &visitor_data) < 0) ERR; /*printf("visitor_data: 0x%x\n", visitor_data);*/ /* There's also a label for each dimension. */ if (H5DSget_label(datasetid, 0, label, STR_LEN) < 0) ERR; if (strcmp(label, TIME_NAME)) ERR; if (H5DSget_label(datasetid, 1, label, STR_LEN) < 0) ERR; if (strcmp(label, LAT_NAME)) ERR; if (H5DSget_label(datasetid, 2, label, STR_LEN) < 0) ERR; if (strcmp(label, LON_NAME)) ERR; } 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 || H5Gclose(grpid) < 0 || H5Fclose(fileid) < 0) ERR; } SUMMARIZE_ERR; printf("*** Creating 3D datasets using shared dimscales in groups..."); { #define FATHER "Adam" #define GOOD_CHILD "Able" #define BAD_CHILD "Cain" #define DISTANCE_LEN 3 #define SMELLINESS_NAME "Smelliness" #define DISTANCE_NAME "Distance" #define TIME_NAME "Time" #define TIME_DIM 0 #define SMELLINESS_DIM 1 #define DISTANCE_DIM 2 #define GOAT_NAME "Billy_goat_gruff" #define CAMEL_NAME "Grumpy_the_camel" hid_t fileid, smelliness_spaceid, distance_spaceid, time_spaceid, spaceid; hid_t adam_grpid, able_grpid, cain_grpid; hid_t time_scaleid, smelliness_scaleid, distance_scaleid; hid_t goat_dsid, camel_dsid, cparmsid; hsize_t dims[NDIMS], max_dims[NDIMS]; /* Create file and group. */ if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) ERR; if ((adam_grpid = H5Gcreate(fileid, FATHER, 0)) < 0) ERR; if ((able_grpid = H5Gcreate(adam_grpid, GOOD_CHILD, 0)) < 0) ERR; if ((cain_grpid = H5Gcreate(adam_grpid, BAD_CHILD, 0)) < 0) ERR; /* Create 3 1D spaces for the 3 dimension scale datasets. Time * and smelliness starts out as 0. They are unlimited dimension * scales. */ dims[0] = 0; max_dims[0] = H5S_UNLIMITED; if ((time_spaceid = H5Screate_simple(1, dims, max_dims)) < 0) ERR; dims[0] = 0; max_dims[0] = H5S_UNLIMITED; if ((smelliness_spaceid = H5Screate_simple(1, dims, max_dims)) < 0) ERR; dims[0] = DISTANCE_LEN; max_dims[0] = DISTANCE_LEN; if ((distance_spaceid = H5Screate_simple(1, dims, max_dims)) < 0) ERR; /* Enable chunking for unlimited time and smelliness scale. */ if ((cparmsid = H5Pcreate(H5P_DATASET_CREATE)) < 0) ERR; dims[0] = 1; if (H5Pset_chunk(cparmsid, 1, dims) < 0) ERR; /* Create our dimension scales. */ if ((time_scaleid = H5Dcreate(adam_grpid, TIME_NAME, H5T_NATIVE_INT, time_spaceid, cparmsid)) < 0) ERR; if (H5DSset_scale(time_scaleid, TIME_NAME) < 0) ERR; if ((smelliness_scaleid = H5Dcreate(adam_grpid, SMELLINESS_NAME, H5T_NATIVE_FLOAT, smelliness_spaceid, cparmsid)) < 0) ERR; if (H5DSset_scale(smelliness_scaleid, SMELLINESS_NAME) < 0) ERR; if ((distance_scaleid = H5Dcreate(adam_grpid, DISTANCE_NAME, H5T_NATIVE_FLOAT, distance_spaceid, H5P_DEFAULT)) < 0) ERR; if (H5DSset_scale(distance_scaleid, DISTANCE_NAME) < 0) ERR; /* Create a space coresponding to these three dimensions. */ dims[TIME_DIM] = 0; dims[SMELLINESS_DIM] = 0; dims[DISTANCE_DIM] = DISTANCE_LEN; max_dims[TIME_DIM] = H5S_UNLIMITED; max_dims[SMELLINESS_DIM] = H5S_UNLIMITED; max_dims[DISTANCE_DIM] = DISTANCE_LEN; if ((spaceid = H5Screate_simple(NDIMS, dims, max_dims)) < 0) ERR; /* Set up chunking for our 3D vars. */ dims[TIME_DIM] = 1; dims[SMELLINESS_DIM] = 1; if (H5Pset_chunk(cparmsid, NDIMS, dims) < 0) ERR; /* Create two variables which use them, and attach the dimension scales. */ if ((goat_dsid = H5Dcreate(able_grpid, GOAT_NAME, H5T_NATIVE_FLOAT, spaceid, cparmsid)) < 0) ERR; if (H5DSattach_scale(goat_dsid, time_scaleid, 0) < 0) ERR; if (H5DSattach_scale(goat_dsid, smelliness_scaleid, 1) < 0) ERR; if (H5DSattach_scale(goat_dsid, distance_scaleid, 2) < 0) ERR; if ((camel_dsid = H5Dcreate(cain_grpid, CAMEL_NAME, H5T_NATIVE_FLOAT, spaceid, cparmsid)) < 0) ERR; if (H5DSattach_scale(camel_dsid, time_scaleid, 0) < 0) ERR; if (H5DSattach_scale(camel_dsid, smelliness_scaleid, 1) < 0) ERR; if (H5DSattach_scale(camel_dsid, distance_scaleid, 2) < 0) ERR; /* Close up the shop. */ if (H5Dclose(goat_dsid) < 0 || H5Dclose(camel_dsid) < 0 || H5Dclose(smelliness_scaleid) < 0 || H5Dclose(distance_scaleid) < 0 || H5Dclose(time_scaleid) < 0 || H5Sclose(spaceid) < 0 || H5Gclose(cain_grpid) < 0 || H5Gclose(able_grpid) < 0 || H5Gclose(adam_grpid) < 0 || H5Fclose(fileid) < 0) ERR; } SUMMARIZE_ERR; printf("*** Checking 3D datasets in groups created with shared dimscales..."); { hid_t fileid, grpid; /* Reopen the file and group. */ if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) ERR; if ((grpid = H5Gopen(fileid, FATHER)) < 0) ERR; /* If we can't scan the group, crash into a flaming heap of * smoking, smoldering rubbish. */ if (rec_scan_group(grpid)) ERR; /* Close up the shop. */ if (H5Gclose(grpid) < 0 || H5Fclose(fileid) < 0) ERR; } SUMMARIZE_ERR; #endif FINAL_RESULTS; }
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; }
/* ****************************************************************************************************************************** */ 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 */