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 #include <unistd.h>
47 
48 #include <hdf5.h>
49 #include <H5Epublic.h>
50 
51 #include <boost/tokenizer.hpp>
52 #include <boost/utility.hpp>
53 
54 #include "Field3DFile.h"
55 #include "Field.h"
56 #include "ClassFactory.h"
57 
58 //----------------------------------------------------------------------------//
59 
60 using namespace std;
61 
62 //----------------------------------------------------------------------------//
63 
65 
66 //----------------------------------------------------------------------------//
67 // Field3D namespaces
68 //----------------------------------------------------------------------------//
69 
70 using namespace Exc;
71 using namespace Hdf5Util;
72 using namespace File;
73 
74 //----------------------------------------------------------------------------//
75 // Local namespace
76 //----------------------------------------------------------------------------//
77 
78 namespace {
79 
80  // Strings used only in this file --------------------------------------------
81 
82  const std::string k_mappingStr("mapping");
83  const std::string k_partitionName("partition");
84  const std::string k_versionAttrName("version_number");
85  const std::string k_classNameAttrName("class_name");
86  const std::string k_mappingTypeAttrName("mapping_type");
87 
90 
91  int k_currentFileVersion[3] =
93  int k_minFileVersion[2] = { 0, 0 };
94 
95  // Function objects used only in this file -----------------------------------
96 
97  std::vector<std::string> makeUnique(std::vector<std::string> vec)
98  {
99  std::vector<string> ret;
100  std::sort(vec.begin(), vec.end());
101  std::vector<std::string>::iterator newEnd =
102  std::unique(vec.begin(), vec.end());
103  ret.resize(std::distance(vec.begin(), newEnd));
104  std::copy(vec.begin(), newEnd, ret.begin());
105  return ret;
106  }
107 
108 //----------------------------------------------------------------------------//
109 
111  template <class T>
112  class print : std::unary_function<T, void>
113  {
114  public:
115  print(int indentAmt)
116  : indent(indentAmt)
117  { }
118  void operator()(const T& x) const
119  {
120  for (int i = 0; i < indent; i++)
121  std::cout << " ";
122  std::cout << x << std::endl;
123  }
124  int indent;
125  };
126 
127 //----------------------------------------------------------------------------//
128 
134  bool fileExists(const std::string &filename)
135  {
136  struct stat statbuf;
137  return (stat(filename.c_str(), &statbuf) != -1);
138  }
139 
145  void checkFile(const std::string &filename)
146  {
147  if (!fileExists(filename))
148  {
149  throw NoSuchFileException(filename);
150  }
151  }
152 
153 //----------------------------------------------------------------------------//
154 
155  bool isSupportedFileVersion(const int fileVersion[3],
156  const int minVersion[2])
157  {
158  stringstream currentVersionStr;
159  currentVersionStr << k_currentFileVersion[0] << "."
160  << k_currentFileVersion[1] << "."
161  << k_currentFileVersion[2];
162  stringstream fileVersionStr;
163  fileVersionStr << fileVersion[0] << "."
164  << fileVersion[1] << "."
165  << fileVersion[2];
166  stringstream minVersionStr;
167  minVersionStr << minVersion[0] << "."
168  << minVersion[1];
169 
170  if (fileVersion[0] > k_currentFileVersion[0] ||
171  (fileVersion[0] == k_currentFileVersion[0] &&
172  fileVersion[1] > k_currentFileVersion[1])) {
173  Msg::print(Msg::SevWarning, "File version " + fileVersionStr.str() +
174  " is higher than the current version " +
175  currentVersionStr.str());
176  return true;
177  }
178 
179  if (fileVersion[0] < minVersion[0] ||
180  (fileVersion[0] == minVersion[0] &&
181  fileVersion[1] < minVersion[1])) {
182  Msg::print(Msg::SevWarning, "File version " + fileVersionStr.str() +
183  " is lower than the minimum supported version " +
184  minVersionStr.str());
185  return false;
186  }
187  return true;
188  }
189 
190 //----------------------------------------------------------------------------//
191 
192  static herr_t localPrintError( hid_t estack_id, void *stream )
193  {
194  printf("H5E message -----------------------\n");
195  return H5Eprint2(estack_id, static_cast<FILE*>(stream));
196  }
197 
198 //----------------------------------------------------------------------------//
199 
200 } // end of local namespace
201 
202 //----------------------------------------------------------------------------//
203 // Partition implementations
204 //----------------------------------------------------------------------------//
205 
206 std::string Partition::className() const
207 {
208  return k_partitionName;
209 }
210 
211 //----------------------------------------------------------------------------//
212 
213 void
214 Partition::addScalarLayer(const Layer &layer)
215 {
216  m_scalarLayers.push_back(layer);
217 }
218 
219 //----------------------------------------------------------------------------//
220 
221 void
222 Partition::addVectorLayer(const Layer &layer)
223 {
224  m_vectorLayers.push_back(layer);
225 }
226 
227 //----------------------------------------------------------------------------//
228 
229 const Layer*
230 Partition::scalarLayer(const std::string &name) const
231 {
232  for (ScalarLayerList::const_iterator i = m_scalarLayers.begin();
233  i != m_scalarLayers.end(); ++i) {
234  if (i->name == name)
235  return &(*i);
236  }
237  return NULL;
238 }
239 
240 //----------------------------------------------------------------------------//
241 
242 const Layer*
243 Partition::vectorLayer(const std::string &name) const
244 {
245  for (VectorLayerList::const_iterator i = m_vectorLayers.begin();
246  i != m_vectorLayers.end(); ++i) {
247  if (i->name == name)
248  return &(*i);
249  }
250  return NULL;
251 }
252 
253 //----------------------------------------------------------------------------//
254 
255 void
256 Partition::getScalarLayerNames(std::vector<std::string> &names) const
257 {
258  // We don't want to do names.clear() here, since this gets called
259  // inside some loops that want to accumulate names.
260  for (ScalarLayerList::const_iterator i = m_scalarLayers.begin();
261  i != m_scalarLayers.end(); ++i) {
262  names.push_back(i->name);
263  }
264 }
265 
266 //----------------------------------------------------------------------------//
267 
268 void
269 Partition::getVectorLayerNames(std::vector<std::string> &names) const
270 {
271  // We don't want to do names.clear() here, since this gets called
272  // inside some loops that want to accumulate names.
273  for (VectorLayerList::const_iterator i = m_vectorLayers.begin();
274  i != m_vectorLayers.end(); ++i) {
275  names.push_back(i->name);
276  }
277 }
278 
279 //----------------------------------------------------------------------------//
280 // Field3DFileBase implementations
281 //----------------------------------------------------------------------------//
282 
284  : m_file(-1), m_metadata(this)
285 {
286  // Suppressing HDF error messages
287  // Explanation about the function for the error stack is here:
288  // http://www.hdfgroup.org/HDF5/doc/RM/RM_H5E.html#Error-SetAuto2
289  if (getenv("DEBUG_HDF")) {
290  cerr << "Field3DFile -- HDF5 messages are on" << endl;
291  H5Eset_auto(H5E_DEFAULT, localPrintError, NULL);
292  } else {
293  H5Eset_auto(H5E_DEFAULT, NULL, NULL);
294  }
295 }
296 
297 //----------------------------------------------------------------------------//
298 
300 {
301  close();
302 }
303 
304 //----------------------------------------------------------------------------//
305 
306 std::string
307 Field3DFileBase::intPartitionName(const std::string &partitionName,
308  const std::string &layerName,
309  FieldRes::Ptr field)
310 {
311  // Loop over existing partitions and see if there's a matching mapping
312  for (PartitionList::const_iterator i = m_partitions.begin();
313  i != m_partitions.end(); ++i) {
314  if (removeUniqueId((**i).name) == partitionName) {
315  if ((**i).mapping->isIdentical(field->mapping())) {
316  return (**i).name;
317  }
318  }
319  }
320 
321  // If there was no previously matching name, then make a new one
322 
323  int nextIdx = -1;
324  if (m_partitionCount.find(partitionName) != m_partitionCount.end()) {
325  nextIdx = ++m_partitionCount[partitionName];
326  } else {
327  nextIdx = 0;
328  m_partitionCount[partitionName] = 0;
329  }
330 
331  return makeIntPartitionName(partitionName, nextIdx);
332 }
333 
334 //----------------------------------------------------------------------------//
335 
336 Partition::Ptr Field3DFileBase::partition(const string &partitionName)
337 {
338  for (PartitionList::iterator i = m_partitions.begin();
339  i != m_partitions.end(); ++i) {
340  if ((**i).name == partitionName)
341  return *i;
342  }
343 
344  return Partition::Ptr();
345 }
346 
347 //----------------------------------------------------------------------------//
348 
350 Field3DFileBase::partition(const string &partitionName) const
351 {
352  for (PartitionList::const_iterator i = m_partitions.begin();
353  i != m_partitions.end(); ++i) {
354  if ((**i).name == partitionName)
355  return *i;
356  }
357 
358  return Partition::Ptr();
359 }
360 
361 //----------------------------------------------------------------------------//
362 
363 std::string
364 Field3DFileBase::removeUniqueId(const std::string &partitionName) const
365 {
366  size_t pos = partitionName.rfind(".");
367  if (pos == partitionName.npos) {
368  return partitionName;
369  } else {
370  return partitionName.substr(0, pos);
371  }
372 }
373 
374 //----------------------------------------------------------------------------//
375 
376 void
377 Field3DFileBase::getPartitionNames(vector<string> &names) const
378 {
379  names.clear();
380 
381  vector<string> tempNames;
382 
383  for (PartitionList::const_iterator i = m_partitions.begin();
384  i != m_partitions.end(); ++i) {
385  tempNames.push_back(removeUniqueId((**i).name));
386  }
387 
388  names = makeUnique(tempNames);
389 }
390 
391 //----------------------------------------------------------------------------//
392 
393 void
395  const string &partitionName) const
396 {
397  names.clear();
398 
399  for (int i = 0; i < numIntPartitions(partitionName); i++) {
400  string internalName = makeIntPartitionName(partitionName, i);
401  Partition::Ptr part = partition(internalName);
402  if (part)
403  part->getScalarLayerNames(names);
404  }
405 
406  names = makeUnique(names);
407 }
408 
409 //----------------------------------------------------------------------------//
410 
411 void
413  const string &partitionName) const
414 {
415  names.clear();
416 
417  for (int i = 0; i < numIntPartitions(partitionName); i++) {
418  string internalName = makeIntPartitionName(partitionName, i);
419  Partition::Ptr part = partition(internalName);
420  if (part)
421  part->getVectorLayerNames(names);
422  }
423 
424  names = makeUnique(names);
425 }
426 
427 //----------------------------------------------------------------------------//
428 
429 void
430 Field3DFileBase::getIntPartitionNames(vector<string> &names) const
431 {
432  names.clear();
433 
434  for (PartitionList::const_iterator i = m_partitions.begin();
435  i != m_partitions.end(); ++i) {
436  names.push_back((**i).name);
437  }
438 }
439 
440 //----------------------------------------------------------------------------//
441 
442 void
444  const string &intPartitionName) const
445 {
446  names.clear();
447 
448  Partition::Ptr part = partition(intPartitionName);
449 
450  if (!part) {
451  Msg::print("getIntScalarLayerNames no partition: " + intPartitionName);
452  return;
453  }
454 
455  part->getScalarLayerNames(names);
456 }
457 
458 //----------------------------------------------------------------------------//
459 
460 void
462  const string &intPartitionName) const
463 {
464  names.clear();
465 
466  Partition::Ptr part = partition(intPartitionName);
467 
468  if (!part) {
469  Msg::print("getIntVectorLayerNames no partition: " + intPartitionName);
470  return;
471  }
472 
473  part->getVectorLayerNames(names);
474 }
475 
476 //----------------------------------------------------------------------------//
477 
479 {
480  closeInternal();
481  m_partitions.clear();
482  m_groupMembership.clear();
483 }
484 
485 //----------------------------------------------------------------------------//
486 
488 {
489  closeInternal();
490 
491  return true;
492 }
493 
494 //----------------------------------------------------------------------------//
495 
497 {
498  if (m_file != -1) {
499  if (H5Fclose(m_file) < 0) {
500  Msg::print(Msg::SevWarning, "Failed to close hdf5 file handle");
501  return;
502  }
503  m_file = -1;
504  }
505 }
506 
507 //----------------------------------------------------------------------------//
508 
509 int
510 Field3DFileBase::numIntPartitions(const std::string &partitionName) const
511 {
512  int count = 0;
513 
514  for (PartitionList::const_iterator i = m_partitions.begin();
515  i != m_partitions.end(); ++i) {
516  string name = (**i).name;
517  size_t pos = name.rfind(".");
518  if (pos != name.npos) {
519  if (name.substr(0, pos) == partitionName) {
520  count++;
521  }
522  }
523  }
524 
525  return count;
526 }
527 
528 //----------------------------------------------------------------------------//
529 
530 string
531 Field3DFileBase::makeIntPartitionName(const std::string &partitionName,
532  int i) const
533 {
534  return partitionName + "." + boost::lexical_cast<std::string>(i);
535 }
536 
537 //----------------------------------------------------------------------------//
538 
539 void
541 {
542  GroupMembershipMap::const_iterator i= groupMembers.begin();
543  GroupMembershipMap::const_iterator end= groupMembers.end();
544 
545  for (; i != end; ++i) {
546  GroupMembershipMap::iterator foundGroupIter =
547  m_groupMembership.find(i->first);
548  if (foundGroupIter != m_groupMembership.end()){
549  std::string value = m_groupMembership[i->first] + i->second;
550  m_groupMembership[i->first] = value;
551  } else {
552  m_groupMembership[i->first] = i->second;
553  }
554  }
555 }
556 
557 //----------------------------------------------------------------------------//
558 // Field3DInputFile implementations
559 //----------------------------------------------------------------------------//
560 
562 {
563  // Empty
564 }
565 
566 //----------------------------------------------------------------------------//
567 
569 {
570  clear();
571 }
572 
573 //----------------------------------------------------------------------------//
574 
575 bool Field3DInputFile::open(const string &filename)
576 {
577  clear();
578 
579  bool success = true;
580 
581  m_filename = filename;
582 
583  try {
584 
585  string version;
586 
587  // Throws exceptions if the file doesn't exist.
588  // This was added because H5Fopen prints out a lot of junk
589  // to the terminal.
590  checkFile(filename);
591 
592  m_file = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
593 
594  if (m_file < 0)
595  throw NoSuchFileException(filename);
596 
597  int fileVersion[3];
598  try {
599  if (!readAttribute(m_file, k_versionAttrName, 3, fileVersion[0])) {
600  //Msg::print(Msg::SevWarning, "Missing version_number attribute");
601  } else {
602  if (!isSupportedFileVersion(fileVersion, k_minFileVersion)) {
603  stringstream versionStr;
604  versionStr << fileVersion[0] << "."
605  << fileVersion[1] << "."
606  << fileVersion[2];
607  throw UnsupportedVersionException(versionStr.str());
608  }
609  }
610  }
611  catch (MissingAttributeException &e) {
612  //Msg::print(Msg::SevWarning, "Missing version_number attribute");
613  }
614 
615  try {
616  if (H5Lexists(m_file, "field3d_global_metadata", H5P_DEFAULT)) {
617  // read the metadata
618  H5ScopedGopen metadataGroup(m_file, "field3d_global_metadata");
619  if (metadataGroup.id() > 0) {
620  readMetadata(metadataGroup.id());
621  }
622  }
623  }
624  catch (...) {
626  "Unknown error when reading file metadata ");
627  //throw BadFileHierarchyException(filename);
628  }
629 
630  try {
631  if (!readPartitionAndLayerInfo()) {
632  success = false;
633  }
634  }
635  catch (MissingGroupException &e) {
636  Msg::print(Msg::SevWarning, "Missing group: " + string(e.what()));
637  throw BadFileHierarchyException(filename);
638  }
639  catch (ReadMappingException &e) {
640  Msg::print(Msg::SevWarning, "Couldn't read mapping for partition: "
641  + string(e.what()));
642  throw BadFileHierarchyException(filename);
643  }
644  catch (Exception &e) {
645  Msg::print(Msg::SevWarning, "Unknown error when reading file hierarchy: "
646  + string(e.what()));
647  throw BadFileHierarchyException(filename);
648  }
649  catch (...) {
651  "Unknown error when reading file hierarchy. ");
652  throw BadFileHierarchyException(filename);
653  }
654 
655  }
656  catch (NoSuchFileException &e) {
657  Msg::print(Msg::SevWarning, "Couldn't open file: "
658  + string(e.what()) );
659  success = false;
660  }
661  catch (MissingAttributeException &e) {
663  "In file: " + filename + " - "
664  + string(e.what()) );
665  success = false;
666  }
667  catch (UnsupportedVersionException &e) {
669  "In file: " + filename + " - File version can not be read: "
670  + string(e.what()));
671  success = false;
672  }
673  catch (BadFileHierarchyException &e) {
675  "In file: " + filename + " - Bad file hierarchy. ");
676  success = false;
677  }
678  catch (...) {
680  "In file: " + filename + " Unknown exception ");
681  success = false;
682  }
683 
684  if (!success)
685  close();
686 
687  return success;
688 }
689 
690 //----------------------------------------------------------------------------//
691 
693 {
694  using namespace InputFile;
695 
696  // First, find the partitions ---
697 
698  herr_t status;
699  status = H5Literate(m_file, H5_INDEX_NAME, H5_ITER_NATIVE, NULL,
700  &parsePartitions, this);
701 
702  // Get the partition names to store
703  m_partitions.clear();
704 
705  for (size_t i=0; i < m_partitionNames.size(); i++) {
706  Partition::Ptr part(new Partition);
707  part->name = m_partitionNames[i];
708  m_partitions.push_back(part);
709  }
710 
711  // For each partition, find its mapping ---
712 
713  for (PartitionList::iterator i = m_partitions.begin();
714  i != m_partitions.end(); ++i) {
715 
716  // Open the partition
717  H5ScopedGopen partitionGroup(m_file, (**i).name);
718 
719  string mappingPath = "/" + (**i).name + "/" + k_mappingStr;
720 
721  // Open up the mapping group
722  H5ScopedGopen mappingGroup(m_file, mappingPath);
723  if (mappingGroup.id() < 0)
724  throw MissingGroupException((**i).name + "/" + k_mappingStr);
725 
726  // Try to build a mapping from it
727  FieldMapping::Ptr mapping;
728 
729  mapping = readFieldMapping(mappingGroup.id());
730  if (!mapping) {
731  Msg::print(Msg::SevWarning, "Got a null pointer when reading mapping");
732  throw ReadMappingException((**i).name);
733  }
734 
735  // Attach the mapping to the partition
736  (**i).mapping = mapping;
737 
738  }
739 
740  // ... And then find its layers ---
741 
742  for (PartitionList::const_iterator i = m_partitions.begin();
743  i != m_partitions.end(); ++i) {
744 
745  // Open the partition
746  H5ScopedGopen partitionGroup(m_file, (**i).name);
747 
748  // Set up the info struct for the callback
749  ParseLayersInfo info;
750  info.file = this;
751  info.partitionName = (**i).name;
752 
753  m_layerInfo.clear();
754 
755  status = H5Literate(partitionGroup.id(), H5_INDEX_NAME, H5_ITER_NATIVE,
756  NULL, &parseLayers, &info);
757 
758  //set the layer information on the partitions here
759 
760  for (std::vector<LayerInfo>::iterator i = m_layerInfo.begin();
761  i != m_layerInfo.end(); i++) {
762 
763  std::string parent = i->parentName;
764 
765  Partition::Ptr part = partition(parent);
766 
767  Layer layer;
768  layer.name = i->name;
769  layer.parent = i->parentName;
770  if (i->components == 1) {
771  part->addScalarLayer(layer);
772  } else if (i->components == 3) {
773  part->addVectorLayer(layer);
774  }
775  }
776 
777  }
778 
779  return true;
780 }
781 
782 //----------------------------------------------------------------------------//
783 
784 herr_t Field3DInputFile::parsePartition(hid_t loc_id,
785  const std::string itemName)
786 {
787  // Add the partition ---
788 
789  m_partitionNames.push_back(string(itemName));
790  return 0;
791 }
792 
793 //----------------------------------------------------------------------------//
794 
798 herr_t Field3DInputFile::parseLayer(hid_t layerGroup,
799  const std::string &partitionName,
800  const std::string &layerName)
801 {
802  int components;
803  if (!readAttribute(layerGroup, string("components"), 1, components)) {
804  Msg::print(Msg::SevWarning, "Couldn't read components attribute for layer "
805  + partitionName + "/" + layerName);
806  return 0;
807  }
808 
809  LayerInfo linfo(partitionName,layerName,components);
810 
811  m_layerInfo.push_back(linfo);
812 
813  return 0;
814 }
815 
816 //----------------------------------------------------------------------------//
817 
819 bool
821 readMetadata(hid_t metadata_id, FieldBase::Ptr field) const
822 {
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 
933  hsize_t num_attrs = H5Aget_num_attrs(metadata_id);
934 
935  if (num_attrs > 0) {
936  for (hsize_t idx=0; idx < num_attrs ; ++idx) {
937  H5ScopedAopenIdx attrIdx(metadata_id, idx);
938  size_t len = H5Aget_name(attrIdx.id(), 0, NULL);
939  if (len > 0) {
940  char *name = new char[len+1];
941  if (H5Aget_name(attrIdx.id(), len+1, name) > 0) {
942  H5ScopedAopen attr(metadata_id, name, H5P_DEFAULT);
943  H5ScopedAget_space attrSpace(attr);
944  H5ScopedAget_type attrType(attr);
945  H5T_class_t typeClass = H5Tget_class(attrType);
946 
947  if (typeClass == H5T_STRING) {
948  string value;
949  if (!readAttribute(metadata_id, name, value)) {
951  "Failed to read metadata " + string(name));
952  if (name) {
953  delete[] name;
954  }
955  continue;
956  }
957  metadata().setStrMetadata(name, value);
958 
959  }
960  else {
961 
962  if (H5Sget_simple_extent_ndims(attrSpace) != 1) {
963  Msg::print(Msg::SevWarning, "Bad attribute rank for attribute "
964  + string(name));
965  if (name) {
966  delete[] name;
967  }
968  continue;
969  }
970 
971  hsize_t dims[1];
972  H5Sget_simple_extent_dims(attrSpace, dims, NULL);
973 
974  if (typeClass == H5T_INTEGER) {
975  if (dims[0] == 1){
976  int value;
977  if (!readAttribute(metadata_id, name, dims[0], value))
978  Msg::print(Msg::SevWarning, "Failed to read metadata "
979  + string(name));
980  metadata().setIntMetadata(name, value);
981  }
982  else if (dims[0] == 3){
983  V3i value;
984  if (!readAttribute(metadata_id, name, dims[0], value.x))
985  Msg::print(Msg::SevWarning, "Failed to read metadata " +
986  string(name) );
987  metadata().setVecIntMetadata(name, value);
988  }
989  else {
991  "Attribute of size " +
992  boost::lexical_cast<std::string>(dims[0])
993  + " is not valid for metadata");
994  }
995  }
996  else if (typeClass == H5T_FLOAT) {
997  if (dims[0] == 1){
998  float value;
999  if (!readAttribute(metadata_id, name, dims[0], value))
1000  Msg::print(Msg::SevWarning, "Failed to read metadata " +
1001  string(name) );
1002 
1003  metadata().setFloatMetadata(name, value);
1004  }
1005  else if (dims[0] == 3){
1006  V3f value;
1007  if (!readAttribute(metadata_id, name, dims[0], value.x))
1008  Msg::print(Msg::SevWarning, "Failed to read metadata "+
1009  string(name) );
1010  metadata().setVecFloatMetadata(name, value);
1011  }
1012  else {
1013  Msg::print(Msg::SevWarning, "Attribute of size " +
1014  boost::lexical_cast<std::string>(dims[0]) +
1015  " is not valid for metadata");
1016  }
1017  }
1018  else {
1019  Msg::print(Msg::SevWarning, "Attribute '" + string(name) +
1020  + "' has unsupported data type for metadata");
1021 
1022  }
1023  }
1024  }
1025  if (name) {
1026  delete[] name;
1027  }
1028  }
1029  }
1030  }
1031 
1032  return true;
1033 }
1034 
1035 //----------------------------------------------------------------------------//
1036 
1037 bool
1040 {
1041  if (!H5Lexists(m_file, "field3d_group_membership", H5P_DEFAULT)) {
1042  return false;
1043  }
1044 
1045  H5ScopedGopen memberGroup(m_file, "field3d_group_membership");
1046  if (memberGroup < 0) {
1047  return false;
1048  }
1049 
1050  typedef boost::tokenizer<boost::char_separator<char> > Tok;
1051 
1052  hsize_t num_attrs = H5Aget_num_attrs(memberGroup);
1053  if (num_attrs > 0) {
1054 
1055  for (hsize_t idx=0; idx < num_attrs ; ++idx) {
1056  H5ScopedAopenIdx attrIdx(memberGroup, idx);
1057  size_t len = H5Aget_name(attrIdx.id(), 0, NULL);
1058  if (len>0) {
1059  char *name = new char[len+1];
1060  if (H5Aget_name(attrIdx.id(), len+1, name) > 0) {
1061 
1062  if (string(name) == "is_field3d_group_membership")
1063  continue;
1064 
1065  H5ScopedAopen attr(memberGroup, name, H5P_DEFAULT);
1066  H5ScopedAget_space attrSpace(attr);
1067  H5ScopedAget_type attrType(attr);
1068  H5T_class_t typeClass = H5Tget_class(attrType);
1069 
1070  if (typeClass == H5T_STRING) {
1071  string value;
1072  if (!readAttribute(memberGroup, name, value)) {
1074  "Failed to read group membership data "
1075  + string(name));
1076  continue;
1077  }
1078 
1079  {
1080  boost::char_separator<char> sep(" :");
1081  Tok tok(value, sep);
1082  string new_value;
1083  for(Tok::iterator beg=tok.begin(); beg!=tok.end();){
1084 
1085  string fieldgroup = *beg; ++beg;
1086  fieldgroup = removeUniqueId(fieldgroup) + ":" + *beg; ++beg;
1087  new_value += fieldgroup + " ";
1088  }
1089 
1090  m_groupMembership[name] = value;
1091  gpMembershipMap[name] = new_value;
1092  }
1093  }
1094  }
1095  }
1096  }
1097  }
1098 
1099  return true;
1100 }
1101 
1102 //----------------------------------------------------------------------------//
1103 // Field3DFile-related callback functions
1104 //----------------------------------------------------------------------------//
1105 
1106 namespace InputFile {
1107 
1108 //----------------------------------------------------------------------------//
1109 
1110 herr_t parsePartitions(hid_t loc_id, const char *itemName,
1111  const H5L_info_t *linfo, void *opdata)
1112 {
1113  herr_t status;
1114  H5O_info_t infobuf;
1115 
1116  status = H5Oget_info_by_name(loc_id, itemName, &infobuf, H5P_DEFAULT);
1117 
1118  if (status < 0) {
1119  return -1;
1120  }
1121 
1122  if (infobuf.type == H5O_TYPE_GROUP) {
1123 
1124  // Check that we have a name
1125  if (!itemName) {
1126  return -1;
1127  }
1128 
1129  // check that this group is not "groupMembership"
1130  if (string(itemName) != "field3d_group_membership" &&
1131  string(itemName) != "field3d_global_metadata")
1132  {
1133 
1134  // Get a pointer to the file data structure
1135  Field3DInputFile* fileObject = static_cast<Field3DInputFile*>(opdata);
1136  if (!fileObject) {
1137  return -1;
1138  }
1139 
1140  return fileObject->parsePartition(loc_id, itemName);
1141  }
1142  }
1143  return 0;
1144 }
1145 
1146 //----------------------------------------------------------------------------//
1147 
1148 herr_t parseLayers(hid_t loc_id, const char *itemName,
1149  const H5L_info_t *linfo, void *opdata)
1150 {
1151  herr_t status;
1152  H5O_info_t infobuf;
1153 
1154  status = H5Oget_info_by_name (loc_id, itemName, &infobuf, H5P_DEFAULT);
1155 
1156  if (infobuf.type == H5O_TYPE_GROUP) {
1157 
1158  // Check that we have a name
1159  if (!itemName)
1160  return -1;
1161 
1162  // Get a pointer to the file data structure
1163  ParseLayersInfo* info = static_cast<ParseLayersInfo*>(opdata);
1164  if (!info)
1165  return -1;
1166 
1167  // Open up the layer group
1168  H5ScopedGopen layerGroup(loc_id, itemName);
1169 
1170  // Check if it's a layer
1171  string classType;
1172  try {
1173  if (!readAttribute(layerGroup.id(), "class_type", classType)) {
1174  return 0;
1175  }
1176  if (classType == string("field3d_layer"))
1177  return info->file->parseLayer(layerGroup.id(), info->partitionName,
1178  itemName);
1179 
1180  }
1181  catch (MissingAttributeException &e) {
1182 
1183  }
1184  return 0;
1185 
1186  }
1187 
1188  return 0;
1189 }
1190 
1191 //----------------------------------------------------------------------------//
1192 
1193 } // namespace InputFile
1194 
1195 //----------------------------------------------------------------------------//
1196 // Field3DOutputFile implementations
1197 //----------------------------------------------------------------------------//
1198 
1200 {
1201  // Empty
1202 }
1203 
1204 //----------------------------------------------------------------------------//
1205 
1207 {
1208 
1209 }
1210 
1211 //----------------------------------------------------------------------------//
1212 
1215 bool Field3DOutputFile::create(const string &filename, CreateMode cm)
1216 {
1217  closeInternal();
1218 
1219  bool success = true;
1220 
1221  try {
1222 
1223  hid_t faid = H5Pcreate(H5P_FILE_ACCESS);
1224  H5Pset_libver_bounds(faid, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST);
1225 
1226  // Create new file
1227  switch (cm) {
1228  case OverwriteMode:
1229  m_file = H5Fcreate(filename.c_str(),
1230  H5F_ACC_TRUNC, H5P_DEFAULT, faid);
1231  break;
1232  case FailOnExisting:
1233  m_file = H5Fcreate(filename.c_str(),
1234  H5F_ACC_EXCL, H5P_DEFAULT, faid);
1235  break;
1236  }
1237 
1238  // Check that file was created
1239  if (m_file < 0)
1240  throw ErrorCreatingFileException(filename);
1241 
1242  // Create a version attribute on the root node
1243  if (!writeAttribute(m_file, k_versionAttrName, 3,
1244  k_currentFileVersion[0])) {
1245  Msg::print(Msg::SevWarning, "Adding version number.");
1246  closeInternal();
1247  return false;
1248  }
1249 
1250  }
1251  catch (ErrorCreatingFileException &e) {
1252  Msg::print(Msg::SevWarning, "Couldn't create file: " + string(e.what()) );
1253  success = false;
1254  }
1255  catch (WriteAttributeException &e) {
1256  Msg::print(Msg::SevWarning, "In file : " + filename +
1257  " - Couldn't add attribute " + string(e.what()) );
1258  success = false;
1259  }
1260  catch (...) {
1262  "Unknown error when creating file: " + filename );
1263  success = false;
1264  }
1265 
1266  return success;
1267 }
1268 
1269 //----------------------------------------------------------------------------//
1270 
1271 bool Field3DOutputFile::writeMapping(hid_t partitionGroup,
1272  FieldMapping::Ptr mapping)
1273 {
1274  try {
1275  // Make a group under the partition to store the mapping data
1276  H5ScopedGcreate mappingGroup(partitionGroup, k_mappingStr);
1277  if (mappingGroup.id() < 0)
1278  throw CreateGroupException(k_mappingStr);
1279  // Let FieldMappingIO handle the rest
1280  if (!writeFieldMapping(mappingGroup.id(), mapping))
1281  throw WriteMappingException(k_mappingStr);
1282  }
1283  catch (CreateGroupException &e) {
1284  Msg::print(Msg::SevWarning, "Couldn't create group: " + string(e.what()) );
1285  throw WriteMappingException(k_mappingStr);
1286  }
1287  return true;
1288 }
1289 
1290 //----------------------------------------------------------------------------//
1291 
1292 bool Field3DOutputFile::writeMetadata(hid_t metadataGroup, FieldBase::Ptr field)
1293 {
1294  using namespace Hdf5Util;
1295 
1296  {
1298  field->metadata().strMetadata().begin();
1300  field->metadata().strMetadata().end();
1301  for (; i != end; ++i) {
1302  if (!writeAttribute(metadataGroup, i->first, i->second))
1303  {
1304  Msg::print(Msg::SevWarning, "Writing attribute " + i->first );
1305  return false;
1306  }
1307  }
1308  }
1309 
1310  {
1312  field->metadata().intMetadata().begin();
1314  field->metadata().intMetadata().end();
1315  for (; i != end; ++i) {
1316  if (!writeAttribute(metadataGroup, i->first, 1, i->second))
1317  {
1318  Msg::print(Msg::SevWarning, "Writing attribute " + i->first);
1319  return false;
1320  }
1321  }
1322  }
1323 
1324  {
1326  field->metadata().floatMetadata().begin();
1328  field->metadata().floatMetadata().end();
1329  for (; i != end; ++i) {
1330  if (!writeAttribute(metadataGroup, i->first, 1, i->second))
1331  {
1332  Msg::print(Msg::SevWarning, "Writing attribute " + i->first);
1333  return false;
1334  }
1335  }
1336  }
1337 
1338  {
1340  field->metadata().vecIntMetadata().begin();
1342  field->metadata().vecIntMetadata().end();
1343  for (; i != end; ++i) {
1344  if (!writeAttribute(metadataGroup, i->first, 3, i->second.x))
1345  {
1346  Msg::print(Msg::SevWarning, "Writing attribute " + i->first);
1347  return false;
1348  }
1349  }
1350  }
1351 
1352  {
1354  field->metadata().vecFloatMetadata().begin();
1356  field->metadata().vecFloatMetadata().end();
1357  for (; i != end; ++i) {
1358  if (!writeAttribute(metadataGroup, i->first, 3, i->second.x))
1359  {
1360  Msg::print(Msg::SevWarning, "Writing attribute " + i->first);
1361  return false;
1362  }
1363  }
1364 
1365  }
1366 
1367  return true;
1368 
1369 }
1370 
1371 //----------------------------------------------------------------------------//
1372 
1373 bool Field3DOutputFile::writeMetadata(hid_t metadataGroup)
1374 {
1375  using namespace Hdf5Util;
1376 
1377  {
1379  metadata().strMetadata().begin();
1381  metadata().strMetadata().end();
1382  for (; i != end; ++i) {
1383  if (!writeAttribute(metadataGroup, i->first, i->second))
1384  {
1385  Msg::print(Msg::SevWarning, "Writing attribute " + i->first );
1386  return false;
1387  }
1388  }
1389  }
1390 
1391  {
1393  metadata().intMetadata().begin();
1395  metadata().intMetadata().end();
1396  for (; i != end; ++i) {
1397  if (!writeAttribute(metadataGroup, i->first, 1, i->second))
1398  {
1399  Msg::print(Msg::SevWarning, "Writing attribute " + i->first);
1400  return false;
1401  }
1402  }
1403  }
1404 
1405  {
1407  metadata().floatMetadata().begin();
1409  metadata().floatMetadata().end();
1410  for (; i != end; ++i) {
1411  if (!writeAttribute(metadataGroup, i->first, 1, i->second))
1412  {
1413  Msg::print(Msg::SevWarning, "Writing attribute " + i->first);
1414  return false;
1415  }
1416  }
1417  }
1418 
1419  {
1421  metadata().vecIntMetadata().begin();
1423  metadata().vecIntMetadata().end();
1424  for (; i != end; ++i) {
1425  if (!writeAttribute(metadataGroup, i->first, 3, i->second.x))
1426  {
1427  Msg::print(Msg::SevWarning, "Writing attribute " + i->first);
1428  return false;
1429  }
1430  }
1431  }
1432 
1433  {
1435  metadata().vecFloatMetadata().begin();
1437  metadata().vecFloatMetadata().end();
1438  for (; i != end; ++i) {
1439  if (!writeAttribute(metadataGroup, i->first, 3, i->second.x))
1440  {
1441  Msg::print(Msg::SevWarning, "Writing attribute " + i->first);
1442  return false;
1443  }
1444  }
1445 
1446  }
1447 
1448  return true;
1449 
1450 }
1451 
1452 //----------------------------------------------------------------------------//
1453 
1454 bool
1456 {
1457 
1458  // Add metadata group and write it out
1459  H5ScopedGcreate metadataGroup(m_file, "field3d_global_metadata");
1460  if (metadataGroup.id() < 0) {
1461  Msg::print(Msg::SevWarning, "Error creating group: file metadata");
1462  return false;
1463  }
1464  if (!writeMetadata(metadataGroup.id())) {
1465  Msg::print(Msg::SevWarning, "Error writing file metadata.");
1466  return false;
1467  }
1468 
1469  return true;
1470 }
1471 
1472 //----------------------------------------------------------------------------//
1473 
1474 bool
1476 {
1477  using namespace std;
1478  using namespace Hdf5Util;
1479 
1480  if (!m_groupMembership.size())
1481  return true;
1482 
1483  H5ScopedGcreate group(m_file, "field3d_group_membership");
1484  if (group < 0) {
1486  "Error creating field3d_group_membership group.");
1487  return false;
1488  }
1489 
1490  if (!writeAttribute(group, "is_field3d_group_membership", "1")) {
1492  "Failed to write field3d_group_membership attribute.");
1493  return false;
1494  }
1495 
1496  std::map<std::string, std::string>::const_iterator iter =
1497  m_groupMembership.begin();
1498  std::map<std::string, std::string>::const_iterator iEnd =
1499  m_groupMembership.end();
1500 
1501  for (; iter != iEnd; ++iter) {
1502  if (!writeAttribute(group, iter->first, iter->second)) {
1504  "Failed to write groupMembership string: "+ iter->first);
1505  return false;
1506  }
1507  }
1508 
1509  return true;
1510 }
1511 
1512 //----------------------------------------------------------------------------//
1513 
1514 std::string
1516 {
1517  std::string myPartitionName = removeUniqueId(partitionName);
1518  int nextIdx = -1;
1519  if (m_partitionCount.find(myPartitionName) != m_partitionCount.end()) {
1520  nextIdx = ++m_partitionCount[myPartitionName];
1521  } else {
1522  nextIdx = 0;
1523  m_partitionCount[myPartitionName] = 0;
1524  }
1525 
1526  return makeIntPartitionName(myPartitionName, nextIdx);
1527 }
1528 
1529 //----------------------------------------------------------------------------//
1530 // Debug
1531 //----------------------------------------------------------------------------//
1532 
1534 {
1535  // For each partition
1536  for (PartitionList::const_iterator i = m_partitions.begin();
1537  i != m_partitions.end(); ++i) {
1538  cout << "Name: " << (**i).name << endl;
1539  if ((**i).mapping)
1540  cout << " Mapping: " << (**i).mapping->className() << endl;
1541  else
1542  cout << " Mapping: NULL" << endl;
1543  cout << " Scalar layers: " << endl;
1544  vector<string> sNames;
1545  (**i).getScalarLayerNames(sNames);
1546  for_each(sNames.begin(), sNames.end(), print<string>(4));
1547  cout << " Vector layers: " << endl;
1548  vector<string> vNames;
1549  (**i).getVectorLayerNames(vNames);
1550  for_each(vNames.begin(), vNames.end(), print<string>(4));
1551  }
1552 }
1553 
1554 //----------------------------------------------------------------------------//
1555 // Function Implementations
1556 //----------------------------------------------------------------------------//
1557 
1558 bool writeField(hid_t layerGroup, FieldBase::Ptr field)
1559 {
1561 
1562  FieldIO::Ptr io = factory.createFieldIO(field->className());
1563  assert(io != 0);
1564  if (!io) {
1565  Msg::print(Msg::SevWarning, "Unable to find class type: " +
1566  field->className());
1567  return false;
1568  }
1569 
1570  // Add class name attribute
1571  if (!writeAttribute(layerGroup, k_classNameAttrName,
1572  field->className())) {
1573  Msg::print(Msg::SevWarning, "Error adding class name attribute.");
1574  return false;
1575  }
1576 
1577  return io->write(layerGroup, field);
1578 }
1579 
1580 //----------------------------------------------------------------------------//
1581 
1583 {
1585 
1586  std::string className;
1587 
1588  if (!readAttribute(mappingGroup, k_mappingTypeAttrName, className)) {
1589  Msg::print(Msg::SevWarning, "Couldn't find " + k_mappingTypeAttrName +
1590  " attribute");
1591  return FieldMapping::Ptr();
1592  }
1593 
1594  FieldMappingIO::Ptr io = factory.createFieldMappingIO(className);
1595  assert(io != 0);
1596  if (!io) {
1597  Msg::print(Msg::SevWarning, "Unable to find class type: " +
1598  className);
1599  return FieldMapping::Ptr();
1600  }
1601 
1602 
1603  FieldMapping::Ptr mapping = io->read(mappingGroup);
1604  if (!mapping) {
1605  Msg::print(Msg::SevWarning, "Couldn't read mapping");
1606  return FieldMapping::Ptr();
1607  }
1608 
1609  return mapping;
1610 }
1611 
1612 //----------------------------------------------------------------------------//
1613 
1614 bool writeFieldMapping(hid_t mappingGroup, FieldMapping::Ptr mapping)
1615 {
1617 
1618  std::string className = mapping->className();
1619 
1620  if (!writeAttribute(mappingGroup, k_mappingTypeAttrName, className)) {
1621  Msg::print(Msg::SevWarning, "Couldn't add " + className + " attribute");
1622  return false;
1623  }
1624 
1625  FieldMappingIO::Ptr io = factory.createFieldMappingIO(className);
1626  assert(io != 0);
1627  if (!io) {
1628  Msg::print(Msg::SevWarning, "Unable to find class type: " +
1629  className);
1630  return false;
1631  }
1632 
1633  return io->write(mappingGroup, mapping);
1634 }
1635 
1636 //----------------------------------------------------------------------------//
1637 
1639 
1640 //----------------------------------------------------------------------------//
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:108
Scoped object - opens an attribute data type on creation and closes it on destruction.
Definition: Hdf5Util.h:283
virtual ~Field3DInputFile()
FieldMappingIO::Ptr createFieldMappingIO(const std::string &className) const
Instances an IO object by name.
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.
int numIntPartitions(const std::string &partitionName) const
Returns the number of internal partitions for a given partition name.
Contains utility functions and classes for Hdf5 files.
Definition: Hdf5Util.h:76
void getVectorLayerNames(std::vector< std::string > &names, const std::string &partitionName) const
Gets the names of all the vector layers in a given partition.
void getScalarLayerNames(std::vector< std::string > &names, const std::string &partitionName) const
Gets the names of all the scalar layers in a given partition.
Contains the Field3DFile classesOSS sanitized.
boost::intrusive_ptr< Partition > Ptr
Definition: Field3DFile.h:149
#define FIELD3D_NAMESPACE_SOURCE_CLOSE
Definition: ns.h:60
Namespace for Exception objects.
Definition: Exception.h:57
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:251
void clear()
Clear the data structures and close the file.
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...
void setFloatMetadata(const std::string &name, const float val)
Set the a float value for the given metadata name.
virtual const char * what() const
Definition: Exception.h:90
void print(Severity severity, const std::string &message)
Sends the string to the assigned output, prefixing the message with the severity. ...
Definition: Log.cpp:62
boost::intrusive_ptr< FieldRes > Ptr
Definition: Field.h:215
bool create(const std::string &filename, CreateMode cm=OverwriteMode)
Creates a .f3d file on disk.
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 ...
Scoped object - creates a group on creation and closes it on destruction.
Definition: Hdf5Util.h:150
void setVecIntMetadata(const std::string &name, const V3i &val)
Set the a V3i value for the given metadata name.
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 ...
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:392
herr_t parsePartition(hid_t loc_id, const std::string partitionName)
Gets called from parsePartitions. Not intended for any other use.
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:103
Imath::V3i V3i
Definition: SpiMathLib.h:71
std::vector< std::string > m_partitionNames
This stores partition names.
Definition: Field3DFile.h:388
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.
void printHierarchy() const
Scoped object - Opens attribute by index and closes it on destruction.
Definition: Hdf5Util.h:129
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 getPartitionNames(std::vector< std::string > &names) const
Gets the names of all the partitions in the file.
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:121
void addGroupMembership(const GroupMembershipMap &groupMembers)
Add to the group membership.
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...
FieldIO::Ptr createFieldIO(const std::string &className) const
Instances an IO object by name.
bool readAttribute(hid_t location, const std::string &attrName, std::string &value)
Reads a string attribute.
#define FIELD3D_MINOR_VER
Definition: ns.h:39
PartitionList m_partitions
Vector of partitions.
Definition: Field3DFile.h:386
void setStrMetadata(const std::string &name, const std::string &val)
Set the a string value for the given metadata name.
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.
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 writeAttribute(hid_t location, const std::string &attrName, const std::string &value)
Writes a string attribute.
Provides reading of .f3d (internally, hdf5) files.Refer to using_files for examples of how to use thi...
Definition: Field3DFile.h:431
virtual ~Field3DFileBase()=0
Pure virtual destructor to ensure we never instantiate this class.
Namespace for file input specifics.
Definition: Field3DFile.h:738
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:262
bool close()
Closes the file. No need to call this unless you specifically want to close the file early...
void getIntPartitionNames(std::vector< std::string > &names) const
Gets the names of all the -internal- partitions in the file.
bool readGroupMembership(GroupMembershipMap &gpMembershipMap)
Read the group membership for the partitions.
std::string removeUniqueId(const std::string &partitionName) const
Strips any unique identifiers from the partition name and returns the original name.
std::vector< LayerInfo > m_layerInfo
This stores layer info.
Definition: Field3DFile.h:381
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:315
Contains Field, WritableField and ResizableField classes.
bool readMetadata(hid_t metadata_id, FieldBase::Ptr field) const
Read metadata for this layer.
Contains the ClassFactory class for registering Field3D classes.
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...
struct used to pass the class and partition info back to the parseLayers() callback ...
Definition: Field3DFile.h:743
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 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 ...
void setIntMetadata(const std::string &name, const int val)
Set the a int value for the given metadata name.
boost::intrusive_ptr< FieldIO > Ptr
Definition: FieldIO.h:90
hid_t id() const
Query the hid_t value.
Definition: Hdf5Util.h:90
#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:384
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:397
#define FIELD3D_MAJOR_VER
Definition: ns.h:38
Field3DInputFile * file
Definition: Field3DFile.h:745
Scoped object - opens a group on creation and closes it on destruction.
Definition: Hdf5Util.h:176
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.
std::string parent
The name of the parent partition. We need this in order to open its group.
Definition: Field3DFile.h:124
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...