MOAB: Mesh Oriented datABase  (version 5.5.0)
dump_geom_sets.cxx
Go to the documentation of this file.
1 // This utility reads a MOAB HDF5 mesh file, and prints out
2 // the list of all geometry entitysets and the parent and
3 // child geometry entitysets of each such entityset.
4 
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <hdf5.h>
8 #include <vector>
9 #include <map>
10 #include <string>
11 
12 // Open HDF5 file
13 hid_t open_file( const char* name )
14 {
15  hid_t handle = H5Fopen( name, H5F_ACC_RDONLY, H5P_DEFAULT );
16  if (handle < 0) {
17  fprintf(stderr, "Cannot open file: \"%s\"\n", name );
18  exit (1);
19  }
20  return handle;
21 }
22 
23 // Read a scalar attribute value from an HDF5 file
24 long read_scalar_attrib( hid_t file, const char* table, const char* attrib )
25 {
26  hid_t table_id = H5Dopen( file, table );
27  if (table_id < 0) {
28  fprintf(stderr, "Invalid file. Data not found: \"%s\"\n", table );
29  exit (1);
30  }
31 
32  hid_t attr_id = H5Aopen_name( table_id, attrib );
33  H5Dclose( table_id );
34  if (attr_id < 0) {
35  fprintf(stderr, "Invalid file. No \"%s\" attrib on \"%s\"\n", attrib, table );
36  exit (1);
37  }
38 
39  long value;
40  herr_t rval = H5Aread( attr_id, H5T_NATIVE_LONG, &value );
41  H5Aclose( attr_id );
42  if (rval < 0) {
43  fprintf(stderr, "Failed to read \"%s\" attrib on \"%s\"\n", attrib, table );
44  exit (2);
45  }
46 
47  return value;
48 }
49 
50 
51 // Read a data table from an HDF5 file
52 void read_data( hid_t file, const char* name, int expected_cols, std::vector<long>& data )
53 {
54  hid_t handle = H5Dopen( file, name );
55  if (handle < 0) {
56  fprintf(stderr, "Invalid file. Data not found: \"%s\"\n", name );
57  exit (1);
58  }
59 
60  hid_t space = H5Dget_space( handle );
61  if (space < 0) {
62  fprintf(stderr, "Internal error accessing: \"%s\"\n", name );
63  exit (2);
64  }
65 
66  int ndims = H5Sget_simple_extent_ndims( space );
67  if (ndims < 0) {
68  fprintf(stderr, "Internal error accessing: \"%s\"\n", name );
69  exit (2);
70  }
71  else if (ndims < 1 || ndims > 2) {
72  fprintf(stderr, "\"%s\" is an %d-dimension table. Corrupt file?", name, ndims );
73  exit (2);
74  }
75 
76  hsize_t dims[2] = { 0, 1 };
77  H5Sget_simple_extent_dims( space, dims, 0 );
78  H5Sclose( space );
79 
80  if (dims[1] != expected_cols) {
81  fprintf(stderr, "Error reading \"%s\": expected %d cols, has %d\n", name, expected_cols, (int)dims[1] );
82  exit (2);
83  }
84 
85  data.resize( dims[0] * dims[1] );
86  herr_t rval = H5Dread( handle, H5T_NATIVE_LONG, H5S_ALL, H5S_ALL, H5P_DEFAULT, &data[0] );
87  if (rval < 0) {
88  fprintf(stderr, "Error reading data from: \"%s\"\n", name );
89  exit (1);
90  }
91 
92  H5Dclose( handle );
93 }
94 
95 // Given two vectors of the same length, create a map where the
96 // key is taken from the first vectgor and the value is taken
97 // from the second vector.
98 void create_map( const std::vector<long>& ents,
99  const std::vector<long>& vals,
100  std::map<long,long>& map,
101  const char* name )
102 {
103  if (ents.size() != vals.size()) {
104  fprintf(stderr, "Invalid data for tag \"%s\": mismatched table lengths.\n", name );
105  exit (1);
106  }
107 
108  std::vector<long>::const_iterator e_iter = ents.begin(), v_iter = vals.begin();
109  for (; e_iter != ents.end(); ++e_iter, ++v_iter)
110  map[*e_iter] = *v_iter;
111 }
112 
113 // Construct a string designator for a geometry entity given
114 // the handle of that geometry entity and maps from handle to
115 // dimension and handle to global id.
116 std::string ent_from_handle( const std::map<long,long>& dimmap,
117  const std::map<long,long>& idmap,
118  long handle )
119 {
120  std::string result;
121  std::map<long,long>::const_iterator d_iter, i_iter;
122  d_iter = dimmap.find( handle );
123  i_iter = idmap.find( handle );
124  if (d_iter == dimmap.end() || i_iter == idmap.end())
125  return result;
126 
127  switch (d_iter->second) {
128  case 0: result += "v"; break;
129  case 1: result += "c"; break;
130  case 2: result += "s"; break;
131  case 3: result += "V"; break;
132  default:
133  fprintf(stderr,"Invalid value in GEOM_DIMENSION tag data.\n");
134  exit (1);
135  }
136 
137  char buffer[128];
138  sprintf(buffer, "%ld", i_iter->second );
139  result += buffer;
140  return result;
141 }
142 
143 // Construct a string designator for list of geometry entities given
144 // a list of handles and maps from handle to
145 // dimension and handle to global id.
146 std::string ent_list_from_handles( const std::map<long,long>& dimmap,
147  const std::map<long,long>& idmap,
148  const std::vector<long>& vect,
149  long start,
150  long stop )
151 {
152  std::string result;
153  if (start >= (long)vect.size() || stop >= (long)vect.size() || stop < start) {
154  fprintf(stderr, "Invalid set data. Corrupt file?\n");
155  exit(2);
156  }
157  std::vector<long>::const_iterator iter = vect.begin() + start+1,
158  end = vect.begin() + stop+1;
159 
160  for (; iter != end; ++iter)
161  {
162  std::string tmp = ent_from_handle( dimmap, idmap, *iter );
163  if (!tmp.empty()) {
164  result += tmp;
165  result += " ";
166  }
167  else
168  result += "? ";
169  }
170  return result;
171 }
172 
173 int main( int argc, char* argv[] )
174 {
175  // Need a file name to read
176  if (argc != 2) {
177  printf("Usage: %s <file>\n", argv[0] );
178  exit(1);
179  }
180 
181  // Read everything we need from the file
182  std::vector<long> set_meta, set_child, set_parent, dim_ents, dim_vals, id_ents, id_vals;
183  hid_t file = open_file( argv[1] );
184  read_data( file, "/tstt/sets/list", 4, set_meta );
185  read_data( file, "/tstt/sets/parents", 1, set_parent );
186  read_data( file, "/tstt/sets/children", 1, set_child );
187  read_data( file, "/tstt/tags/GEOM_DIMENSION/id_list", 1, dim_ents );
188  read_data( file, "/tstt/tags/GEOM_DIMENSION/values", 1, dim_vals );
189  read_data( file, "/tstt/tags/GLOBAL_ID/id_list", 1, id_ents );
190  read_data( file, "/tstt/tags/GLOBAL_ID/values", 1, id_vals );
191  const long startid = read_scalar_attrib( file, "/tstt/sets/list", "start_id" );
192  H5Fclose( file );
193 
194  // Construct handle->dimension and handle->global_id maps.
195  std::map<long,long> dimmap, idmap;
196  create_map( dim_ents, dim_vals, dimmap, "GEOM_DIMENSION" );
197  create_map( id_ents, id_vals, idmap, "GLOBAL_ID" );
198 
199  // For each entity set
200  long parent_start = -1l, child_start = -1l;
201  printf("handle ID Children Parents\n");
202  for (unsigned i = 0; i < set_meta.size(); i += 4)
203  {
204  // Get name
205  long handle = startid + i/4;
206  std::string name = ent_from_handle( dimmap, idmap, handle );
207  if (name.empty()) // not a geometry set
208  continue;
209 
210  // Get parents and children
211  long child_end = set_meta[i+1];
212  long parent_end = set_meta[i+2];
213  std::string children = ent_list_from_handles( dimmap, idmap, set_child, child_start, child_end );
214  std::string parents = ent_list_from_handles( dimmap, idmap, set_parent, parent_start, parent_end );
215  child_start = child_end;
216  parent_start = parent_end;
217 
218  // Print
219  printf( "%6ld %-6s %-20s %-20s\n", handle, name.c_str(), children.c_str(), parents.c_str() );
220  }
221 
222  return 0;
223 }