Field3D
Field3DFile.cpp
Go to the documentation of this file.
1 //----------------------------------------------------------------------------//
2 
3 /*
4  * Copyright (c) 2009 Sony Pictures Imageworks Inc
5  *
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the
17  * distribution. Neither the name of Sony Pictures Imageworks nor the
18  * names of its contributors may be used to endorse or promote
19  * products derived from this software without specific prior written
20  * permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
33  * OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 //----------------------------------------------------------------------------//
37 
43 //----------------------------------------------------------------------------//
44 
45 #include <sys/stat.h>
46 #ifndef WIN32
47 #include <unistd.h>
48 #endif
49 
50 #include <hdf5.h>
51 #include <H5Epublic.h>
52 
53 #include <boost/tokenizer.hpp>
54 #include <boost/utility.hpp>
55 
56 #include "Field3DFile.h"
57 #include "Field.h"
58 #include "ClassFactory.h"
59 
60 //----------------------------------------------------------------------------//
61 
62 using namespace std;
63 
64 //----------------------------------------------------------------------------//
65 
67 
68 //----------------------------------------------------------------------------//
69 // Field3D namespaces
70 //----------------------------------------------------------------------------//
71 
72 using namespace Exc;
73 using namespace Hdf5Util;
74 using namespace File;
75 
76 //----------------------------------------------------------------------------//
77 // Local namespace
78 //----------------------------------------------------------------------------//
79 
80 namespace {
81 
82  // Strings used only in this file --------------------------------------------
83 
84  const std::string k_mappingStr("mapping");
85  const std::string k_partitionName("partition");
86  const std::string k_versionAttrName("version_number");
87  const std::string k_classNameAttrName("class_name");
88  const std::string k_mappingTypeAttrName("mapping_type");
89 
92 
93  int k_currentFileVersion[3] =
95  int k_minFileVersion[2] = { 0, 0 };
96 
97  // Function objects used only in this file -----------------------------------
98 
99  std::vector<std::string> makeUnique(std::vector<std::string> vec)
100  {
101  std::vector<string> ret;
102  std::sort(vec.begin(), vec.end());
103  std::vector<std::string>::iterator newEnd =
104  std::unique(vec.begin(), vec.end());
105  ret.resize(std::distance(vec.begin(), newEnd));
106  std::copy(vec.begin(), newEnd, ret.begin());
107  return ret;
108  }
109 
110  //--------------------------------------------------------------------------//
111 
113  template <class T>
114  class print : std::unary_function<T, void>
115  {
116  public:
117  print(int indentAmt)
118  : indent(indentAmt)
119  { }
120  void operator()(const T& x) const
121  {
122  for (int i = 0; i < indent; i++)
123  std::cout << " ";
124  std::cout << x << std::endl;
125  }
126  int indent;
127  };
128 
129  //--------------------------------------------------------------------------//
130 
136  void checkFile(const std::string &filename)
137  {
138  if (!fileExists(filename))
139  {
140  throw NoSuchFileException(filename);
141  }
142  }
143 
144  //--------------------------------------------------------------------------//
145 
146  bool isSupportedFileVersion(const int fileVersion[3],
147  const int minVersion[2])
148  {
149  stringstream currentVersionStr;
150  currentVersionStr << k_currentFileVersion[0] << "."
151  << k_currentFileVersion[1] << "."
152  << k_currentFileVersion[2];
153  stringstream fileVersionStr;
154  fileVersionStr << fileVersion[0] << "."
155  << fileVersion[1] << "."
156  << fileVersion[2];
157  stringstream minVersionStr;
158  minVersionStr << minVersion[0] << "."
159  << minVersion[1];
160 
161  if (fileVersion[0] > k_currentFileVersion[0] ||
162  (fileVersion[0] == k_currentFileVersion[0] &&
163  fileVersion[1] > k_currentFileVersion[1])) {
164  Msg::print(Msg::SevWarning, "File version " + fileVersionStr.str() +
165  " is higher than the current version " +
166  currentVersionStr.str());
167  return true;
168  }
169 
170  if (fileVersion[0] < minVersion[0] ||
171  (fileVersion[0] == minVersion[0] &&
172  fileVersion[1] < minVersion[1])) {
173  Msg::print(Msg::SevWarning, "File version " + fileVersionStr.str() +
174  " is lower than the minimum supported version " +
175  minVersionStr.str());
176  return false;
177  }
178  return true;
179  }
180 
181  //--------------------------------------------------------------------------//
182 
183  static herr_t localPrintError( hid_t estack_id, void *stream )
184  {
185  printf("H5E message -----------------------\n");
186  return H5Eprint2(estack_id, static_cast<FILE*>(stream));
187  }
188 
189  //--------------------------------------------------------------------------//
190 
191 } // end of local namespace
192 
193 //----------------------------------------------------------------------------//
194 // Partition implementations
195 //----------------------------------------------------------------------------//
196 
197 std::string Partition::className() const
198 {
199  return k_partitionName;
200 }
201 
202 //----------------------------------------------------------------------------//
203 
204 void
205 Partition::addScalarLayer(const Layer &layer)
206 {
207  m_scalarLayers.push_back(layer);
208 }
209 
210 //----------------------------------------------------------------------------//
211 
212 void
213 Partition::addVectorLayer(const Layer &layer)
214 {
215  m_vectorLayers.push_back(layer);
216 }
217 
218 //----------------------------------------------------------------------------//
219 
220 const Layer*
221 Partition::scalarLayer(const std::string &name) const
222 {
223  for (ScalarLayerList::const_iterator i = m_scalarLayers.begin();
224  i != m_scalarLayers.end(); ++i) {
225  if (i->name == name)
226  return &(*i);
227  }
228  return NULL;
229 }
230 
231 //----------------------------------------------------------------------------//
232 
233 const Layer*
234 Partition::vectorLayer(const std::string &name) const
235 {
236  for (VectorLayerList::const_iterator i = m_vectorLayers.begin();
237  i != m_vectorLayers.end(); ++i) {
238  if (i->name == name)
239  return &(*i);
240  }
241  return NULL;
242 }
243 
244 //----------------------------------------------------------------------------//
245 
246 void
247 Partition::getScalarLayerNames(std::vector<std::string> &names) const
248 {
249  // We don't want to do names.clear() here, since this gets called
250  // inside some loops that want to accumulate names.
251  for (ScalarLayerList::const_iterator i = m_scalarLayers.begin();
252  i != m_scalarLayers.end(); ++i) {
253  names.push_back(i->name);
254  }
255 }
256 
257 //----------------------------------------------------------------------------//
258 
259 void
260 Partition::getVectorLayerNames(std::vector<std::string> &names) const
261 {
262  // We don't want to do names.clear() here, since this gets called
263  // inside some loops that want to accumulate names.
264  for (VectorLayerList::const_iterator i = m_vectorLayers.begin();
265  i != m_vectorLayers.end(); ++i) {
266  names.push_back(i->name);
267  }
268 }
269 
270 //----------------------------------------------------------------------------//
271 // Field3DFileBase implementations
272 //----------------------------------------------------------------------------//
273 
275  : m_file(-1), m_metadata(this)
276 {
277  GlobalLock lock(g_hdf5Mutex);
278 
279  // Suppressing HDF error messages
280  // Explanation about the function for the error stack is here:
281  // http://www.hdfgroup.org/HDF5/doc/RM/RM_H5E.html#Error-SetAuto2
282  if (getenv("DEBUG_HDF")) {
283  cerr << "Field3DFile -- HDF5 messages are on" << endl;
284  H5Eset_auto(H5E_DEFAULT, localPrintError, NULL);
285  } else {
286  H5Eset_auto(H5E_DEFAULT, NULL, NULL);
287  }
288 }
289 
290 //----------------------------------------------------------------------------//
291 
293 {
294  close();
295 }
296 
297 //----------------------------------------------------------------------------//
298 
299 std::string
300 Field3DFileBase::intPartitionName(const std::string &partitionName,
301  const std::string & /* layerName */,
302  FieldRes::Ptr field)
303 {
304  // Loop over existing partitions and see if there's a matching mapping
305  for (PartitionList::const_iterator i = m_partitions.begin();
306  i != m_partitions.end(); ++i) {
307  if (removeUniqueId((**i).name) == partitionName) {
308  if ((**i).mapping->isIdentical(field->mapping())) {
309  return (**i).name;
310  }
311  }
312  }
313 
314  // If there was no previously matching name, then make a new one
315 
316  int nextIdx = -1;
317  if (m_partitionCount.find(partitionName) != m_partitionCount.end()) {
318  nextIdx = ++m_partitionCount[partitionName];
319  } else {
320  nextIdx = 0;
321  m_partitionCount[partitionName] = 0;
322  }
323 
324  return makeIntPartitionName(partitionName, nextIdx);
325 }
326 
327 //----------------------------------------------------------------------------//
328 
329 Partition::Ptr Field3DFileBase::partition(const string &partitionName)
330 {
331  for (PartitionList::iterator i = m_partitions.begin();
332  i != m_partitions.end(); ++i) {
333  if ((**i).name == partitionName)
334  return *i;
335  }
336 
337  return Partition::Ptr();
338 }
339 
340 //----------------------------------------------------------------------------//
341 
343 Field3DFileBase::partition(const string &partitionName) const
344 {
345  for (PartitionList::const_iterator i = m_partitions.begin();
346  i != m_partitions.end(); ++i) {
347  if ((**i).name == partitionName)
348  return *i;
349  }
350 
351  return Partition::Ptr();
352 }
353 
354 //----------------------------------------------------------------------------//
355 
356 std::string
357 Field3DFileBase::removeUniqueId(const std::string &partitionName) const
358 {
359  size_t pos = partitionName.rfind(".");
360  if (pos == partitionName.npos) {
361  return partitionName;
362  } else {
363  return partitionName.substr(0, pos);
364  }
365 }
366 
367 //----------------------------------------------------------------------------//
368 
369 void
370 Field3DFileBase::getPartitionNames(vector<string> &names) const
371 {
372  names.clear();
373 
374  vector<string> tempNames;
375 
376  for (PartitionList::const_iterator i = m_partitions.begin();
377  i != m_partitions.end(); ++i) {
378  tempNames.push_back(removeUniqueId((**i).name));
379  }
380 
381  names = makeUnique(tempNames);
382 }
383 
384 //----------------------------------------------------------------------------//
385 
386 void
388  const string &partitionName) const
389 {
390  names.clear();
391 
392  for (int i = 0; i < numIntPartitions(partitionName); i++) {
393  string internalName = makeIntPartitionName(partitionName, i);
394  Partition::Ptr part = partition(internalName);
395  if (part)
396  part->getScalarLayerNames(names);
397  }
398 
399  names = makeUnique(names);
400 }
401 
402 //----------------------------------------------------------------------------//
403 
404 void
406  const string &partitionName) const
407 {
408  names.clear();
409 
410  for (int i = 0; i < numIntPartitions(partitionName); i++) {
411  string internalName = makeIntPartitionName(partitionName, i);
412  Partition::Ptr part = partition(internalName);
413  if (part)
414  part->getVectorLayerNames(names);
415  }
416 
417  names = makeUnique(names);
418 }
419 
420 //----------------------------------------------------------------------------//
421 
422 void
423 Field3DFileBase::getIntPartitionNames(vector<string> &names) const
424 {
425  names.clear();
426 
427  for (PartitionList::const_iterator i = m_partitions.begin();
428  i != m_partitions.end(); ++i) {
429  names.push_back((**i).name);
430  }
431 }
432 
433 //----------------------------------------------------------------------------//
434 
435 void
437  const string &intPartitionName) const
438 {
439  names.clear();
440 
441  Partition::Ptr part = partition(intPartitionName);
442 
443  if (!part) {
444  Msg::print("getIntScalarLayerNames no partition: " + intPartitionName);
445  return;
446  }
447 
448  part->getScalarLayerNames(names);
449 }
450 
451 //----------------------------------------------------------------------------//
452 
453 void
455  const string &intPartitionName) const
456 {
457  names.clear();
458 
459  Partition::Ptr part = partition(intPartitionName);
460 
461  if (!part) {
462  Msg::print("getIntVectorLayerNames no partition: " + intPartitionName);
463  return;
464  }
465 
466  part->getVectorLayerNames(names);
467 }
468 
469 //----------------------------------------------------------------------------//
470 
472 {
473  closeInternal();
474  m_partitions.clear();
475  m_groupMembership.clear();
476 }
477 
478 //----------------------------------------------------------------------------//
479 
481 {
482  closeInternal();
483 
484  return true;
485 }
486 
487 //----------------------------------------------------------------------------//
488 
490 {
491  GlobalLock lock(g_hdf5Mutex);
492 
493  if (m_file != -1) {
494  if (H5Fclose(m_file) < 0) {
495  Msg::print(Msg::SevWarning, "Failed to close hdf5 file handle");
496  return;
497  }
498  m_file = -1;
499  }
500 }
501 
502 //----------------------------------------------------------------------------//
503 
504 int
505 Field3DFileBase::numIntPartitions(const std::string &partitionName) const
506 {
507  int count = 0;
508 
509  for (PartitionList::const_iterator i = m_partitions.begin();
510  i != m_partitions.end(); ++i) {
511  string name = (**i).name;
512  size_t pos = name.rfind(".");
513  if (pos != name.npos) {
514  if (name.substr(0, pos) == partitionName) {
515  count++;
516  }
517  }
518  }
519 
520  return count;
521 }
522 
523 //----------------------------------------------------------------------------//
524 
525 string
526 Field3DFileBase::makeIntPartitionName(const std::string &partitionName,
527  int i) const
528 {
529  return partitionName + "." + boost::lexical_cast<std::string>(i);
530 }
531 
532 //----------------------------------------------------------------------------//
533 
534 void
536 {
537  GroupMembershipMap::const_iterator i= groupMembers.begin();
538  GroupMembershipMap::const_iterator end= groupMembers.end();
539 
540  for (; i != end; ++i) {
541  GroupMembershipMap::iterator foundGroupIter =
542  m_groupMembership.find(i->first);
543  if (foundGroupIter != m_groupMembership.end()){
544  std::string value = m_groupMembership[i->first] + i->second;
545  m_groupMembership[i->first] = value;
546  } else {
547  m_groupMembership[i->first] = i->second;
548  }
549  }
550 }
551 
552 //----------------------------------------------------------------------------//
553 // Field3DInputFile implementations
554 //----------------------------------------------------------------------------//
555 
557 {
558  // Empty
559 }
560 
561 //----------------------------------------------------------------------------//
562 
564 {
565  clear();
566 }
567 
568 //----------------------------------------------------------------------------//
569 
570 bool Field3DInputFile::open(const string &filename)
571 {
572  GlobalLock lock(g_hdf5Mutex);
573 
574  clear();
575 
576  bool success = true;
577 
578  m_filename = filename;
579 
580  try {
581 
582  string version;
583 
584  // Throws exceptions if the file doesn't exist.
585  // This was added because H5Fopen prints out a lot of junk
586  // to the terminal.
587  checkFile(filename);
588 
589  m_file = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
590 
591  if (m_file < 0)
592  throw NoSuchFileException(filename);
593 
594  int fileVersion[3];
595  try {
596  if (!readAttribute(m_file, k_versionAttrName, 3, fileVersion[0])) {
597  //Msg::print(Msg::SevWarning, "Missing version_number attribute");
598  } else {
599  if (!isSupportedFileVersion(fileVersion, k_minFileVersion)) {
600  stringstream versionStr;
601  versionStr << fileVersion[0] << "."
602  << fileVersion[1] << "."
603  << fileVersion[2];
604  throw UnsupportedVersionException(versionStr.str());
605  }
606  }
607  }
608  catch (MissingAttributeException &) {
609  //Msg::print(Msg::SevWarning, "Missing version_number attribute");
610  }
611 
612  try {
613  if (H5Lexists(m_file, "field3d_global_metadata", H5P_DEFAULT)) {
614  // read the metadata
615  H5ScopedGopen metadataGroup(m_file, "field3d_global_metadata");
616  if (metadataGroup.id() > 0) {
617  readMetadata(metadataGroup.id());
618  }
619  }
620  }
621  catch (...) {
623  "Unknown error when reading file metadata ");
624  //throw BadFileHierarchyException(filename);
625  }
626 
627  try {
628  if (!readPartitionAndLayerInfo()) {
629  success = false;
630  }
631  }
632  catch (MissingGroupException &e) {
633  Msg::print(Msg::SevWarning, "Missing group: " + string(e.what()));
634  throw BadFileHierarchyException(filename);
635  }
636  catch (ReadMappingException &e) {
637  Msg::print(Msg::SevWarning, "Couldn't read mapping for partition: "
638  + string(e.what()));
639  throw BadFileHierarchyException(filename);
640  }
641  catch (Exception &e) {
642  Msg::print(Msg::SevWarning, "Unknown error when reading file hierarchy: "
643  + string(e.what()));
644  throw BadFileHierarchyException(filename);
645  }
646  catch (...) {
648  "Unknown error when reading file hierarchy. ");
649  throw BadFileHierarchyException(filename);
650  }
651 
652  }
653  catch (NoSuchFileException &e) {
654  Msg::print(Msg::SevWarning, "Couldn't open file: "
655  + string(e.what()) );
656  success = false;
657  }
658  catch (MissingAttributeException &e) {
660  "In file: " + filename + " - "
661  + string(e.what()) );
662  success = false;
663  }
664  catch (UnsupportedVersionException &e) {
666  "In file: " + filename + " - File version can not be read: "
667  + string(e.what()));
668  success = false;
669  }
670  catch (BadFileHierarchyException &) {
672  "In file: " + filename + " - Bad file hierarchy. ");
673  success = false;
674  }
675  catch (...) {
677  "In file: " + filename + " Unknown exception ");
678  success = false;
679  }
680 
681  if (!success)
682  close();
683 
684  return success;
685 }
686 
687 //----------------------------------------------------------------------------//
688 
690 {
691  using namespace InputFile;
692 
693  GlobalLock lock(g_hdf5Mutex);
694 
695  // First, find the partitions ---
696 
697  herr_t status;
698  status = H5Literate(m_file, H5_INDEX_NAME, H5_ITER_NATIVE, NULL,
699  &parsePartitions, this);
700 
701  // Get the partition names to store
702  m_partitions.clear();
703 
704  for (size_t i=0; i < m_partitionNames.size(); i++) {
705  Partition::Ptr part(new Partition);
706  part->name = m_partitionNames[i];
707  m_partitions.push_back(part);
708  }
709 
710  // For each partition, find its mapping ---
711 
712  for (PartitionList::iterator i = m_partitions.begin();
713  i != m_partitions.end(); ++i) {
714 
715  // Open the partition
716  H5ScopedGopen partitionGroup(m_file, (**i).name);
717 
718  string mappingPath = "/" + (**i).name + "/" + k_mappingStr;
719 
720  // Open up the mapping group
721  H5ScopedGopen mappingGroup(m_file, mappingPath);
722  if (mappingGroup.id() < 0)
723  throw MissingGroupException((**i).name + "/" + k_mappingStr);
724 
725  // Try to build a mapping from it
726  FieldMapping::Ptr mapping;
727 
728  mapping = readFieldMapping(mappingGroup.id());
729  if (!mapping) {
730  Msg::print(Msg::SevWarning, "Got a null pointer when reading mapping");
731  throw ReadMappingException((**i).name);
732  }
733 
734  // Attach the mapping to the partition
735  (**i).mapping = mapping;
736 
737  }
738 
739  // ... And then find its layers ---
740 
741  for (PartitionList::const_iterator i = m_partitions.begin();
742  i != m_partitions.end(); ++i) {
743 
744  // Open the partition
745  H5ScopedGopen partitionGroup(m_file, (**i).name);
746 
747  // Set up the info struct for the callback
748  ParseLayersInfo info;
749  info.file = this;
750  info.partitionName = (**i).name;
751 
752  m_layerInfo.clear();
753 
754  status = H5Literate(partitionGroup.id(), H5_INDEX_NAME, H5_ITER_NATIVE,
755  NULL, &parseLayers, &info);
756 
757  //set the layer information on the partitions here
758 
759  for (std::vector<LayerInfo>::iterator i = m_layerInfo.begin();
760  i != m_layerInfo.end(); i++) {
761 
762  std::string parent = i->parentName;
763 
764  Partition::Ptr part = partition(parent);
765 
766  Layer layer;
767  layer.name = i->name;
768  layer.parent = i->parentName;
769  if (i->components == 1) {
770  part->addScalarLayer(layer);
771  } else if (i->components == 3) {
772  part->addVectorLayer(layer);
773  }
774  }
775 
776  }
777 
778  return true;
779 }
780 
781 //----------------------------------------------------------------------------//
782 
783 herr_t Field3DInputFile::parsePartition(hid_t /* loc_id */,
784  const std::string itemName)
785 {
786  // Add the partition ---
787 
788  m_partitionNames.push_back(string(itemName));
789  return 0;
790 }
791 
792 //----------------------------------------------------------------------------//
793 
797 herr_t Field3DInputFile::parseLayer(hid_t layerGroup,
798  const std::string &partitionName,
799  const std::string &layerName)
800 {
801  int components;
802  if (!readAttribute(layerGroup, string("components"), 1, components)) {
803  Msg::print(Msg::SevWarning, "Couldn't read components attribute for layer "
804  + partitionName + "/" + layerName);
805  return 0;
806  }
807 
808  LayerInfo linfo(partitionName,layerName,components);
809 
810  m_layerInfo.push_back(linfo);
811 
812  return 0;
813 }
814 
815 //----------------------------------------------------------------------------//
816 
818 bool
820 readMetadata(hid_t metadata_id, FieldBase::Ptr field) const
821 {
822  GlobalLock lock(g_hdf5Mutex);
823 
824  hsize_t num_attrs = H5Aget_num_attrs(metadata_id);
825 
826  if (num_attrs > 0) {
827  for (hsize_t idx=0; idx < num_attrs ; ++idx) {
828  H5ScopedAopenIdx attrIdx(metadata_id, idx);
829  size_t len = H5Aget_name(attrIdx.id(), 0, NULL);
830  if (len > 0) {
831  char *name = new char[len+1];
832  if (H5Aget_name(attrIdx.id(), len+1, name) > 0) {
833  H5ScopedAopen attr(metadata_id, name, H5P_DEFAULT);
834  H5ScopedAget_space attrSpace(attr);
835  H5ScopedAget_type attrType(attr);
836  H5T_class_t typeClass = H5Tget_class(attrType);
837 
838  if (typeClass == H5T_STRING) {
839  string value;
840  if (!readAttribute(metadata_id, name, value)) {
842  "Failed to read metadata " + string(name));
843  if (name) {
844  delete[] name;
845  }
846  continue;
847  }
848  field->metadata().setStrMetadata(name, value);
849 
850  }
851  else {
852 
853  if (H5Sget_simple_extent_ndims(attrSpace) != 1) {
854  Msg::print(Msg::SevWarning, "Bad attribute rank for attribute "
855  + string(name));
856  if (name) {
857  delete[] name;
858  }
859  continue;
860  }
861 
862  hsize_t dims[1];
863  H5Sget_simple_extent_dims(attrSpace, dims, NULL);
864 
865  if (typeClass == H5T_INTEGER) {
866  if (dims[0] == 1){
867  int value;
868  if (!readAttribute(metadata_id, name, dims[0], value))
869  Msg::print(Msg::SevWarning, "Failed to read metadata "
870  + string(name));
871  field->metadata().setIntMetadata(name, value);
872  }
873  else if (dims[0] == 3){
874  V3i value;
875  if (!readAttribute(metadata_id, name, dims[0], value.x))
876  Msg::print(Msg::SevWarning, "Failed to read metadata " +
877  string(name) );
878  field->metadata().setVecIntMetadata(name, value);
879  }
880  else {
882  "Attribute of size " +
883  boost::lexical_cast<std::string>(dims[0])
884  + " is not valid for metadata");
885  }
886  }
887  else if (typeClass == H5T_FLOAT) {
888  if (dims[0] == 1){
889  float value;
890  if (!readAttribute(metadata_id, name, dims[0], value))
891  Msg::print(Msg::SevWarning, "Failed to read metadata " +
892  string(name) );
893 
894  field->metadata().setFloatMetadata(name, value);
895  }
896  else if (dims[0] == 3){
897  V3f value;
898  if (!readAttribute(metadata_id, name, dims[0], value.x))
899  Msg::print(Msg::SevWarning, "Failed to read metadata "+
900  string(name) );
901  field->metadata().setVecFloatMetadata(name, value);
902  }
903  else {
904  Msg::print(Msg::SevWarning, "Attribute of size " +
905  boost::lexical_cast<std::string>(dims[0]) +
906  " is not valid for metadata");
907  }
908  }
909  else {
910  Msg::print(Msg::SevWarning, "Attribute '" + string(name) +
911  + "' has unsupported data type for metadata");
912 
913  }
914  }
915  }
916  if (name) {
917  delete[] name;
918  }
919  }
920  }
921  }
922 
923  return true;
924 }
925 
926 //----------------------------------------------------------------------------//
927 
929 bool
931 {
932  GlobalLock lock(g_hdf5Mutex);
933 
934  hsize_t num_attrs = H5Aget_num_attrs(metadata_id);
935 
936  if (num_attrs > 0) {
937  for (hsize_t idx=0; idx < num_attrs ; ++idx) {
938  H5ScopedAopenIdx attrIdx(metadata_id, idx);
939  size_t len = H5Aget_name(attrIdx.id(), 0, NULL);
940  if (len > 0) {
941  char *name = new char[len+1];
942  if (H5Aget_name(attrIdx.id(), len+1, name) > 0) {
943  H5ScopedAopen attr(metadata_id, name, H5P_DEFAULT);
944  H5ScopedAget_space attrSpace(attr);
945  H5ScopedAget_type attrType(attr);
946  H5T_class_t typeClass = H5Tget_class(attrType);
947 
948  if (typeClass == H5T_STRING) {
949  string value;
950  if (!readAttribute(metadata_id, name, value)) {
952  "Failed to read metadata " + string(name));
953  if (name) {
954  delete[] name;
955  }
956  continue;
957  }
958  metadata().setStrMetadata(name, value);
959 
960  }
961  else {
962 
963  if (H5Sget_simple_extent_ndims(attrSpace) != 1) {
964  Msg::print(Msg::SevWarning, "Bad attribute rank for attribute "
965  + string(name));
966  if (name) {
967  delete[] name;
968  }
969  continue;
970  }
971 
972  hsize_t dims[1];
973  H5Sget_simple_extent_dims(attrSpace, dims, NULL);
974 
975  if (typeClass == H5T_INTEGER) {
976  if (dims[0] == 1){
977  int value;
978  if (!readAttribute(metadata_id, name, dims[0], value))
979  Msg::print(Msg::SevWarning, "Failed to read metadata "
980  + string(name));
981  metadata().setIntMetadata(name, value);
982  }
983  else if (dims[0] == 3){
984  V3i value;
985  if (!readAttribute(metadata_id, name, dims[0], value.x))
986  Msg::print(Msg::SevWarning, "Failed to read metadata " +
987  string(name) );
988  metadata().setVecIntMetadata(name, value);
989  }
990  else {
992  "Attribute of size " +
993  boost::lexical_cast<std::string>(dims[0])
994  + " is not valid for metadata");
995  }
996  }
997  else if (typeClass == H5T_FLOAT) {
998  if (dims[0] == 1){
999  float value;
1000  if (!readAttribute(metadata_id, name, dims[0], value))
1001  Msg::print(Msg::SevWarning, "Failed to read metadata " +
1002  string(name) );
1003 
1004  metadata().setFloatMetadata(name, value);
1005  }
1006  else if (dims[0] == 3){
1007  V3f value;
1008  if (!readAttribute(metadata_id, name, dims[0], value.x))
1009  Msg::print(Msg::SevWarning, "Failed to read metadata "+
1010  string(name) );
1011  metadata().setVecFloatMetadata(name, value);
1012  }
1013  else {
1014  Msg::print(Msg::SevWarning, "Attribute of size " +
1015  boost::lexical_cast<std::string>(dims[0]) +
1016  " is not valid for metadata");
1017  }
1018  }
1019  else {
1020  Msg::print(Msg::SevWarning, "Attribute '" + string(name) +
1021  + "' has unsupported data type for metadata");
1022 
1023  }
1024  }
1025  }
1026  if (name) {
1027  delete[] name;
1028  }
1029  }
1030  }
1031  }
1032 
1033  return true;
1034 }
1035 
1036 //----------------------------------------------------------------------------//
1037 
1038 bool
1041 {
1042  GlobalLock lock(g_hdf5Mutex);
1043 
1044  if (!H5Lexists(m_file, "field3d_group_membership", H5P_DEFAULT)) {
1045  return false;
1046  }
1047 
1048  H5ScopedGopen memberGroup(m_file, "field3d_group_membership");
1049  if (memberGroup < 0) {
1050  return false;
1051  }
1052 
1053  typedef boost::tokenizer<boost::char_separator<char> > Tok;
1054 
1055  hsize_t num_attrs = H5Aget_num_attrs(memberGroup);
1056  if (num_attrs > 0) {
1057 
1058  for (hsize_t idx=0; idx < num_attrs ; ++idx) {
1059  H5ScopedAopenIdx attrIdx(memberGroup, idx);
1060  size_t len = H5Aget_name(attrIdx.id(), 0, NULL);
1061  if (len>0) {
1062  char *name = new char[len+1];
1063  if (H5Aget_name(attrIdx.id(), len+1, name) > 0) {
1064 
1065  if (string(name) == "is_field3d_group_membership")
1066  continue;
1067 
1068  H5ScopedAopen attr(memberGroup, name, H5P_DEFAULT);
1069  H5ScopedAget_space attrSpace(attr);
1070  H5ScopedAget_type attrType(attr);
1071  H5T_class_t typeClass = H5Tget_class(attrType);
1072 
1073  if (typeClass == H5T_STRING) {
1074  string value;
1075  if (!readAttribute(memberGroup, name, value)) {
1077  "Failed to read group membership data "
1078  + string(name));
1079  continue;
1080  }
1081 
1082  {
1083  boost::char_separator<char> sep(" :");
1084  Tok tok(value, sep);
1085  string new_value;
1086  for(Tok::iterator beg=tok.begin(); beg!=tok.end();){
1087 
1088  string fieldgroup = *beg; ++beg;
1089  fieldgroup = removeUniqueId(fieldgroup) + ":" + *beg; ++beg;
1090  new_value += fieldgroup + " ";
1091  }
1092 
1093  m_groupMembership[name] = value;
1094  gpMembershipMap[name] = new_value;
1095  }
1096  }
1097  }
1098  }
1099  }
1100  }
1101 
1102  return true;
1103 }
1104 
1105 //----------------------------------------------------------------------------//
1106 // Field3DFile-related callback functions
1107 //----------------------------------------------------------------------------//
1108 
1109 namespace InputFile {
1110 
1111 //----------------------------------------------------------------------------//
1112 
1113 herr_t parsePartitions(hid_t loc_id, const char *itemName,
1114  const H5L_info_t * /* linfo */, void *opdata)
1115 {
1116  GlobalLock lock(g_hdf5Mutex);
1117 
1118  herr_t status;
1119  H5O_info_t infobuf;
1120 
1121  status = H5Oget_info_by_name(loc_id, itemName, &infobuf, H5P_DEFAULT);
1122 
1123  if (status < 0) {
1124  return -1;
1125  }
1126 
1127  if (infobuf.type == H5O_TYPE_GROUP) {
1128 
1129  // Check that we have a name
1130  if (!itemName) {
1131  return -1;
1132  }
1133 
1134  // check that this group is not "groupMembership"
1135  if (string(itemName) != "field3d_group_membership" &&
1136  string(itemName) != "field3d_global_metadata")
1137  {
1138 
1139  // Get a pointer to the file data structure
1140  Field3DInputFile* fileObject = static_cast<Field3DInputFile*>(opdata);
1141  if (!fileObject) {
1142  return -1;
1143  }
1144 
1145  return fileObject->parsePartition(loc_id, itemName);
1146  }
1147  }
1148  return 0;
1149 }
1150 
1151 //----------------------------------------------------------------------------//
1152 
1153 herr_t parseLayers(hid_t loc_id, const char *itemName,
1154  const H5L_info_t * /* linfo */, void *opdata)
1155 {
1156  GlobalLock lock(g_hdf5Mutex);
1157 
1158  herr_t status;
1159  H5O_info_t infobuf;
1160 
1161  status = H5Oget_info_by_name (loc_id, itemName, &infobuf, H5P_DEFAULT);
1162 
1163  if (infobuf.type == H5O_TYPE_GROUP) {
1164 
1165  // Check that we have a name
1166  if (!itemName)
1167  return -1;
1168 
1169  // Get a pointer to the file data structure
1170  ParseLayersInfo* info = static_cast<ParseLayersInfo*>(opdata);
1171  if (!info)
1172  return -1;
1173 
1174  // Open up the layer group
1175  H5ScopedGopen layerGroup(loc_id, itemName);
1176 
1177  // Check if it's a layer
1178  string classType;
1179  try {
1180  if (!readAttribute(layerGroup.id(), "class_type", classType)) {
1181  return 0;
1182  }
1183  if (classType == string("field3d_layer"))
1184  return info->file->parseLayer(layerGroup.id(), info->partitionName,
1185  itemName);
1186 
1187  }
1188  catch (MissingAttributeException &) {
1189 
1190  }
1191  return 0;
1192 
1193  }
1194 
1195  return 0;
1196 }
1197 
1198 //----------------------------------------------------------------------------//
1199 
1200 } // namespace InputFile
1201 
1202 //----------------------------------------------------------------------------//
1203 // Field3DOutputFile implementations
1204 //----------------------------------------------------------------------------//
1205 
1207 {
1208  // Empty
1209 }
1210 
1211 //----------------------------------------------------------------------------//
1212 
1214 {
1215 
1216 }
1217 
1218 //----------------------------------------------------------------------------//
1219 
1222 bool Field3DOutputFile::create(const string &filename, CreateMode cm)
1223 {
1224  GlobalLock lock(g_hdf5Mutex);
1225 
1226  closeInternal();
1227 
1228  bool success = true;
1229 
1230  try {
1231 
1232  hid_t faid = H5Pcreate(H5P_FILE_ACCESS);
1233  H5Pset_libver_bounds(faid, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST);
1234 
1235  // Create new file
1236  switch (cm) {
1237  case OverwriteMode:
1238  m_file = H5Fcreate(filename.c_str(),
1239  H5F_ACC_TRUNC, H5P_DEFAULT, faid);
1240  break;
1241  case FailOnExisting:
1242  m_file = H5Fcreate(filename.c_str(),
1243  H5F_ACC_EXCL, H5P_DEFAULT, faid);
1244  break;
1245  }
1246 
1247  // Check that file was created
1248  if (m_file < 0)
1249  throw ErrorCreatingFileException(filename);
1250 
1251  // Create a version attribute on the root node
1252  if (!writeAttribute(m_file, k_versionAttrName, 3,
1253  k_currentFileVersion[0])) {
1254  Msg::print(Msg::SevWarning, "Adding version number.");
1255  closeInternal();
1256  return false;
1257  }
1258 
1259  }
1260  catch (ErrorCreatingFileException &e) {
1261  Msg::print(Msg::SevWarning, "Couldn't create file: " + string(e.what()) );
1262  success = false;
1263  }
1264  catch (WriteAttributeException &e) {
1265  Msg::print(Msg::SevWarning, "In file : " + filename +
1266  " - Couldn't add attribute " + string(e.what()) );
1267  success = false;
1268  }
1269  catch (...) {
1271  "Unknown error when creating file: " + filename );
1272  success = false;
1273  }
1274 
1275  return success;
1276 }
1277 
1278 //----------------------------------------------------------------------------//
1279 
1280 bool Field3DOutputFile::writeMapping(hid_t partitionGroup,
1281  FieldMapping::Ptr mapping)
1282 {
1283  GlobalLock lock(g_hdf5Mutex);
1284 
1285  try {
1286  // Make a group under the partition to store the mapping data
1287  H5ScopedGcreate mappingGroup(partitionGroup, k_mappingStr);
1288  if (mappingGroup.id() < 0)
1289  throw CreateGroupException(k_mappingStr);
1290  // Let FieldMappingIO handle the rest
1291  if (!writeFieldMapping(mappingGroup.id(), mapping))
1292  throw WriteMappingException(k_mappingStr);
1293  }
1294  catch (CreateGroupException &e) {
1295  Msg::print(Msg::SevWarning, "Couldn't create group: " + string(e.what()) );
1296  throw WriteMappingException(k_mappingStr);
1297  }
1298  return true;
1299 }
1300 
1301 //----------------------------------------------------------------------------//
1302 
1303 bool Field3DOutputFile::writeMetadata(hid_t metadataGroup, FieldBase::Ptr field)
1304 {
1305  using namespace Hdf5Util;
1306 
1307  {
1309  field->metadata().strMetadata().begin();
1311  field->metadata().strMetadata().end();
1312  for (; i != end; ++i) {
1313  if (!writeAttribute(metadataGroup, i->first, i->second))
1314  {
1315  Msg::print(Msg::SevWarning, "Writing attribute " + i->first );
1316  return false;
1317  }
1318  }
1319  }
1320 
1321  {
1323  field->metadata().intMetadata().begin();
1325  field->metadata().intMetadata().end();
1326  for (; i != end; ++i) {
1327  if (!writeAttribute(metadataGroup, i->first, 1, i->second))
1328  {
1329  Msg::print(Msg::SevWarning, "Writing attribute " + i->first);
1330  return false;
1331  }
1332  }
1333  }
1334 
1335  {
1337  field->metadata().floatMetadata().begin();
1339  field->metadata().floatMetadata().end();
1340  for (; i != end; ++i) {
1341  if (!writeAttribute(metadataGroup, i->first, 1, i->second))
1342  {
1343  Msg::print(Msg::SevWarning, "Writing attribute " + i->first);
1344  return false;
1345  }
1346  }
1347  }
1348 
1349  {
1351  field->metadata().vecIntMetadata().begin();
1353  field->metadata().vecIntMetadata().end();
1354  for (; i != end; ++i) {
1355  if (!writeAttribute(metadataGroup, i->first, 3, i->second.x))
1356  {
1357  Msg::print(Msg::SevWarning, "Writing attribute " + i->first);
1358  return false;
1359  }
1360  }
1361  }
1362 
1363  {
1365  field->metadata().vecFloatMetadata().begin();
1367  field->metadata().vecFloatMetadata().end();
1368  for (; i != end; ++i) {
1369  if (!writeAttribute(metadataGroup, i->first, 3, i->second.x))
1370  {
1371  Msg::print(Msg::SevWarning, "Writing attribute " + i->first);
1372  return false;
1373  }
1374  }
1375 
1376  }
1377 
1378  return true;
1379 
1380 }
1381 
1382 //----------------------------------------------------------------------------//
1383 
1384 bool Field3DOutputFile::writeMetadata(hid_t metadataGroup)
1385 {
1386  using namespace Hdf5Util;
1387 
1388  {
1390  metadata().strMetadata().begin();
1392  metadata().strMetadata().end();
1393  for (; i != end; ++i) {
1394  if (!writeAttribute(metadataGroup, i->first, i->second))
1395  {
1396  Msg::print(Msg::SevWarning, "Writing attribute " + i->first );
1397  return false;
1398  }
1399  }
1400  }
1401 
1402  {
1404  metadata().intMetadata().begin();
1406  metadata().intMetadata().end();
1407  for (; i != end; ++i) {
1408  if (!writeAttribute(metadataGroup, i->first, 1, i->second))
1409  {
1410  Msg::print(Msg::SevWarning, "Writing attribute " + i->first);
1411  return false;
1412  }
1413  }
1414  }
1415 
1416  {
1418  metadata().floatMetadata().begin();
1420  metadata().floatMetadata().end();
1421  for (; i != end; ++i) {
1422  if (!writeAttribute(metadataGroup, i->first, 1, i->second))
1423  {
1424  Msg::print(Msg::SevWarning, "Writing attribute " + i->first);
1425  return false;
1426  }
1427  }
1428  }
1429 
1430  {
1432  metadata().vecIntMetadata().begin();
1434  metadata().vecIntMetadata().end();
1435  for (; i != end; ++i) {
1436  if (!writeAttribute(metadataGroup, i->first, 3, i->second.x))
1437  {
1438  Msg::print(Msg::SevWarning, "Writing attribute " + i->first);
1439  return false;
1440  }
1441  }
1442  }
1443 
1444  {
1446  metadata().vecFloatMetadata().begin();
1448  metadata().vecFloatMetadata().end();
1449  for (; i != end; ++i) {
1450  if (!writeAttribute(metadataGroup, i->first, 3, i->second.x))
1451  {
1452  Msg::print(Msg::SevWarning, "Writing attribute " + i->first);
1453  return false;
1454  }
1455  }
1456 
1457  }
1458 
1459  return true;
1460 
1461 }
1462 
1463 //----------------------------------------------------------------------------//
1464 
1465 bool
1467 {
1468  GlobalLock lock(g_hdf5Mutex);
1469 
1470  // Add metadata group and write it out
1471  H5ScopedGcreate metadataGroup(m_file, "field3d_global_metadata");
1472  if (metadataGroup.id() < 0) {
1473  Msg::print(Msg::SevWarning, "Error creating group: file metadata");
1474  return false;
1475  }
1476  if (!writeMetadata(metadataGroup.id())) {
1477  Msg::print(Msg::SevWarning, "Error writing file metadata.");
1478  return false;
1479  }
1480 
1481  return true;
1482 }
1483 
1484 //----------------------------------------------------------------------------//
1485 
1486 bool
1488 {
1489  using namespace std;
1490  using namespace Hdf5Util;
1491 
1492  GlobalLock lock(g_hdf5Mutex);
1493 
1494  if (!m_groupMembership.size())
1495  return true;
1496 
1497  H5ScopedGcreate group(m_file, "field3d_group_membership");
1498  if (group < 0) {
1500  "Error creating field3d_group_membership group.");
1501  return false;
1502  }
1503 
1504  if (!writeAttribute(group, "is_field3d_group_membership", "1")) {
1506  "Failed to write field3d_group_membership attribute.");
1507  return false;
1508  }
1509 
1510  std::map<std::string, std::string>::const_iterator iter =
1511  m_groupMembership.begin();
1512  std::map<std::string, std::string>::const_iterator iEnd =
1513  m_groupMembership.end();
1514 
1515  for (; iter != iEnd; ++iter) {
1516  if (!writeAttribute(group, iter->first, iter->second)) {
1518  "Failed to write groupMembership string: "+ iter->first);
1519  return false;
1520  }
1521  }
1522 
1523  return true;
1524 }
1525 
1526 //----------------------------------------------------------------------------//
1527 
1528 std::string
1530 {
1531  std::string myPartitionName = removeUniqueId(partitionName);
1532  int nextIdx = -1;
1533  if (m_partitionCount.find(myPartitionName) != m_partitionCount.end()) {
1534  nextIdx = ++m_partitionCount[myPartitionName];
1535  } else {
1536  nextIdx = 0;
1537  m_partitionCount[myPartitionName] = 0;
1538  }
1539 
1540  return makeIntPartitionName(myPartitionName, nextIdx);
1541 }
1542 
1543 //----------------------------------------------------------------------------//
1544 // Debug
1545 //----------------------------------------------------------------------------//
1546 
1548 {
1549  // For each partition
1550  for (PartitionList::const_iterator i = m_partitions.begin();
1551  i != m_partitions.end(); ++i) {
1552  cout << "Name: " << (**i).name << endl;
1553  if ((**i).mapping)
1554  cout << " Mapping: " << (**i).mapping->className() << endl;
1555  else
1556  cout << " Mapping: NULL" << endl;
1557  cout << " Scalar layers: " << endl;
1558  vector<string> sNames;
1559  (**i).getScalarLayerNames(sNames);
1560  for_each(sNames.begin(), sNames.end(), print<string>(4));
1561  cout << " Vector layers: " << endl;
1562  vector<string> vNames;
1563  (**i).getVectorLayerNames(vNames);
1564  for_each(vNames.begin(), vNames.end(), print<string>(4));
1565  }
1566 }
1567 
1568 //----------------------------------------------------------------------------//
1569 // Function Implementations
1570 //----------------------------------------------------------------------------//
1571 
1572 bool fileExists(const std::string &filename)
1573 {
1574 #ifdef WIN32
1575  struct __stat64 statbuf;
1576  return (_stat64(filename.c_str(), &statbuf) != -1);
1577 #else
1578  struct stat statbuf;
1579  return (stat(filename.c_str(), &statbuf) != -1);
1580 #endif
1581 }
1582 
1583 //----------------------------------------------------------------------------//
1584 
1585 bool writeField(hid_t layerGroup, FieldBase::Ptr field)
1586 {
1588 
1589  FieldIO::Ptr io = factory.createFieldIO(field->className());
1590  assert(io != 0);
1591  if (!io) {
1592  Msg::print(Msg::SevWarning, "Unable to find class type: " +
1593  field->className());
1594  return false;
1595  }
1596 
1597  // Add class name attribute
1598  if (!writeAttribute(layerGroup, k_classNameAttrName,
1599  field->className())) {
1600  Msg::print(Msg::SevWarning, "Error adding class name attribute.");
1601  return false;
1602  }
1603 
1604  return io->write(layerGroup, field);
1605 }
1606 
1607 //----------------------------------------------------------------------------//
1608 
1610 {
1612 
1613  std::string className;
1614 
1615  if (!readAttribute(mappingGroup, k_mappingTypeAttrName, className)) {
1616  Msg::print(Msg::SevWarning, "Couldn't find " + k_mappingTypeAttrName +
1617  " attribute");
1618  return FieldMapping::Ptr();
1619  }
1620 
1621  FieldMappingIO::Ptr io = factory.createFieldMappingIO(className);
1622  assert(io != 0);
1623  if (!io) {
1624  Msg::print(Msg::SevWarning, "Unable to find class type: " +
1625  className);
1626  return FieldMapping::Ptr();
1627  }
1628 
1629 
1630  FieldMapping::Ptr mapping = io->read(mappingGroup);
1631  if (!mapping) {
1632  Msg::print(Msg::SevWarning, "Couldn't read mapping");
1633  return FieldMapping::Ptr();
1634  }
1635 
1636  return mapping;
1637 }
1638 
1639 //----------------------------------------------------------------------------//
1640 
1641 bool writeFieldMapping(hid_t mappingGroup, FieldMapping::Ptr mapping)
1642 {
1644 
1645  std::string className = mapping->className();
1646 
1647  if (!writeAttribute(mappingGroup, k_mappingTypeAttrName, className)) {
1648  Msg::print(Msg::SevWarning, "Couldn't add " + className + " attribute");
1649  return false;
1650  }
1651 
1652  FieldMappingIO::Ptr io = factory.createFieldMappingIO(className);
1653  assert(io != 0);
1654  if (!io) {
1655  Msg::print(Msg::SevWarning, "Unable to find class type: " +
1656  className);
1657  return false;
1658  }
1659 
1660  return io->write(mappingGroup, mapping);
1661 }
1662 
1663 //----------------------------------------------------------------------------//
1664 
1666 
1667 //----------------------------------------------------------------------------//
FIELD3D_API herr_t parseLayers(hid_t loc_id, const char *partitionName, const H5L_info_t *linfo, void *opdata)
Gets called from readPartitionAndLayerInfo to check each group found under the root of the file...
Namespace for file I/O specifics.
Definition: Field3DFile.h:111
Scoped object - opens an attribute data type on creation and closes it on destruction.
Definition: Hdf5Util.h:310
virtual ~Field3DInputFile()
bool writeGroupMembership()
This routine is called just before closing to write out any group membership to disk.
boost::intrusive_ptr< FieldMappingIO > Ptr
bool writeGlobalMetadata()
This routine is call if you want to write out global metadata to disk.
virtual const char * what() const
Definition: Exception.h:90
Contains utility functions and classes for Hdf5 files.
Definition: Hdf5Util.h:86
FIELD3D_API bool writeAttribute(hid_t location, const std::string &attrName, const std::string &value)
Writes a string attribute.
Contains the Field3DFile classesOSS sanitized.
boost::intrusive_ptr< Partition > Ptr
Definition: Field3DFile.h:152
#define FIELD3D_NAMESPACE_SOURCE_CLOSE
Definition: ns.h:60
Namespace for Exception objects.
Definition: Exception.h:57
void getIntVectorLayerNames(std::vector< std::string > &names, const std::string &intPartitionName) const
Gets the names of all the vector layers in a given partition, but assumes that partition name is the ...
bool writeMetadata(hid_t metadataGroup, FieldBase::Ptr layer)
Writes metadata for this layer.
V3f vecFloatMetadata(const std::string &name, const V3f &defaultVal) const
Tries to retrieve a V3f metadata value. Returns the specified default value if no metadata was found...
std::map< std::string, std::string > GroupMembershipMap
Definition: Field3DFile.h:254
void clear()
Clear the data structures and close the file.
FIELD3D_API bool readAttribute(hid_t location, const std::string &attrName, std::string &value)
Reads a string attribute.
boost::intrusive_ptr< FieldBase > Ptr
Definition: Field.h:97
static ClassFactory & singleton()
}
bool writeField(hid_t layerGroup, FieldBase::Ptr field)
This function creates a FieldIO instance based on field->className() which then writes the field data...
boost::recursive_mutex::scoped_lock GlobalLock
Definition: Hdf5Util.h:78
void setFloatMetadata(const std::string &name, const float val)
Set the a float value for the given metadata name.
FIELD3D_API void print(Severity severity, const std::string &message)
Sends the string to the assigned output, prefixing the message with the severity. ...
Definition: Log.cpp:66
boost::intrusive_ptr< FieldRes > Ptr
Definition: Field.h:218
bool create(const std::string &filename, CreateMode cm=OverwriteMode)
Creates a .f3d file on disk.
void getIntScalarLayerNames(std::vector< std::string > &names, const std::string &intPartitionName) const
Gets the names of all the scalar layers in a given partition, but assumes that partition name is the ...
File::Partition::Ptr partition(const std::string &partitionName)
Returns a pointer to the given partition.
std::string intPartitionName(const std::string &partitionName, const std::string &layerName, FieldRes::Ptr field)
Returns a unique partition name given the requested name. This ensures that partitions with matching ...
void getIntPartitionNames(std::vector< std::string > &names) const
Gets the names of all the -internal- partitions in the file.
Scoped object - creates a group on creation and closes it on destruction.
Definition: Hdf5Util.h:165
void setVecIntMetadata(const std::string &name, const V3i &val)
Set the a V3i value for the given metadata name.
PartitionCountMap m_partitionCount
Contains a counter for each partition name. This is used to keep multiple fields with the same name u...
Definition: Field3DFile.h:395
herr_t parsePartition(hid_t loc_id, const std::string partitionName)
Gets called from parsePartitions. Not intended for any other use.
std::string removeUniqueId(const std::string &partitionName) const
Strips any unique identifiers from the partition name and returns the original name.
herr_t parseLayer(hid_t loc_id, const std::string &partitionName, const std::string &layerName)
Gets called from parsePartitions. Not intended for any other use.
bool readPartitionAndLayerInfo()
Sets up all the partitions and layers, but does not load any data.
Scoped object - Opens attribute by name and closes it on destruction.
Definition: Hdf5Util.h:113
Imath::V3i V3i
Definition: SpiMathLib.h:71
std::vector< std::string > m_partitionNames
This stores partition names.
Definition: Field3DFile.h:391
boost::intrusive_ptr< FieldMapping > Ptr
Definition: FieldMapping.h:92
void setVecFloatMetadata(const std::string &name, const V3f &val)
Set the a V3f value for the given metadata name.
Scoped object - Opens attribute by index and closes it on destruction.
Definition: Hdf5Util.h:142
FieldMapping::Ptr readFieldMapping(hid_t mappingGroup)
This function creates a FieldMappingIO instance based on className read from mappingGroup location wh...
std::string name
The name of the layer (always available)
Definition: Field3DFile.h:124
std::string makeIntPartitionName(const std::string &partitionsName, int i) const
Makes an internal partition name given the external partition name. Effectively just tacks on ...
void addGroupMembership(const GroupMembershipMap &groupMembers)
Add to the group membership.
void printHierarchy() const
int numIntPartitions(const std::string &partitionName) const
Returns the number of internal partitions for a given partition name.
#define FIELD3D_MINOR_VER
Definition: ns.h:39
PartitionList m_partitions
Vector of partitions.
Definition: Field3DFile.h:389
void setStrMetadata(const std::string &name, const std::string &val)
Set the a string value for the given metadata name.
float floatMetadata(const std::string &name, const float defaultVal) const
Tries to retrieve a float metadata value. Returns the specified default value if no metadata was foun...
bool writeMapping(hid_t partitionLocation, FieldMapping::Ptr mapping)
Writes the mapping to the given hdf5 node. Mappings are assumed to be light-weight enough to be store...
void closeInternal()
Closes the file if open.
Provides reading of .f3d (internally, hdf5) files.Refer to using_files for examples of how to use thi...
Definition: Field3DFile.h:434
virtual ~Field3DFileBase()=0
Pure virtual destructor to ensure we never instantiate this class.
Namespace for file input specifics.
Definition: Field3DFile.h:876
Imath::V3f V3f
Definition: SpiMathLib.h:73
virtual ~Field3DOutputFile()
Scoped object - opens an attribute data space on creation and closes it on destruction.
Definition: Hdf5Util.h:287
bool close()
Closes the file. No need to call this unless you specifically want to close the file early...
void getPartitionNames(std::vector< std::string > &names) const
Gets the names of all the partitions in the file.
int intMetadata(const std::string &name, const int defaultVal) const
Tries to retrieve an int metadata value. Returns the specified default value if no metadata was found...
bool readGroupMembership(GroupMembershipMap &gpMembershipMap)
Read the group membership for the partitions.
bool readMetadata(hid_t metadata_id, FieldBase::Ptr field) const
Read metadata for this layer.
FIELD3D_NAMESPACE_OPEN FIELD3D_API boost::recursive_mutex g_hdf5Mutex
Definition: Hdf5Util.cpp:67
std::vector< LayerInfo > m_layerInfo
This stores layer info.
Definition: Field3DFile.h:384
bool writeFieldMapping(hid_t mappingGroup, FieldMapping::Ptr mapping)
This function creates a FieldMappingIO instance based on mapping->className() which then writes Field...
FieldMetadata< Field3DFileBase > & metadata()
accessor to the m_metadata class
Definition: Field3DFile.h:318
Contains Field, WritableField and ResizableField classes.
V3i vecIntMetadata(const std::string &name, const V3i &defaultVal) const
Tries to retrieve a V3i metadata value. Returns the specified default value if no metadata was found...
Contains the ClassFactory class for registering Field3D classes.
FieldIO::Ptr createFieldIO(const std::string &className) const
Instances an IO object by name.
struct used to pass the class and partition info back to the parseLayers() callback ...
Definition: Field3DFile.h:881
FIELD3D_API herr_t parsePartitions(hid_t loc_id, const char *partitionName, const H5L_info_t *linfo, void *opdata)
Gets called from readPartitionAndLayerInfo to check each group found under the root of the file...
void setIntMetadata(const std::string &name, const int val)
Set the a int value for the given metadata name.
void getScalarLayerNames(std::vector< std::string > &names, const std::string &partitionName) const
Gets the names of all the scalar layers in a given partition.
boost::intrusive_ptr< FieldIO > Ptr
Definition: FieldIO.h:90
bool fileExists(const std::string &filename)
checks to see if a file/directory exists or not
#define FIELD3D_MICRO_VER
Definition: ns.h:40
hid_t m_file
The hdf5 id of the current file. Will be -1 if no file is open.
Definition: Field3DFile.h:387
GroupMembershipMap m_groupMembership
Keeps track of group membership for each layer of partition name. The key is the "group" and the valu...
Definition: Field3DFile.h:400
std::string strMetadata(const std::string &name, const std::string &defaultVal) const
Tries to retrieve a string metadata value. Returns the specified default value if no metadata was fou...
#define FIELD3D_MAJOR_VER
Definition: ns.h:38
Field3DInputFile * file
Definition: Field3DFile.h:883
Scoped object - opens a group on creation and closes it on destruction.
Definition: Hdf5Util.h:194
void getVectorLayerNames(std::vector< std::string > &names, const std::string &partitionName) const
Gets the names of all the vector layers in a given partition.
std::string incrementPartitionName(std::string &pname)
increment the partition or make it zero if there&#39;s not an integer suffix
bool open(const std::string &filename)
Opens the given file.
FieldMappingIO::Ptr createFieldMappingIO(const std::string &className) const
Instances an IO object by name.
std::string parent
The name of the parent partition. We need this in order to open its group.
Definition: Field3DFile.h:127
hid_t id() const
Query the hid_t value.
Definition: Hdf5Util.h:100