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...
Scoped object - opens an attribute data type on creation and closes it on destruction.
Definition: Hdf5Util.h:283
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 the Field3DFile classesOSS sanitized.
boost::intrusive_ptr< Partition > Ptr
Definition: Field3DFile.h:149
std::string m_filename
Filename, only to be set by open().
Definition: Field3DFile.h:603
#define FIELD3D_NAMESPACE_SOURCE_CLOSE
Definition: ns.h:60
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: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.
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.
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:150
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:392
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: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.
Scoped object - Opens attribute by index and closes it on destruction.
Definition: Hdf5Util.h:129
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
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
bool readAttribute(hid_t location, const std::string &attrName, std::string &value)
Reads a string attribute.
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:386
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.
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.
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 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.
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.
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: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 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
#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
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:745
Scoped object - opens a group on creation and closes it on destruction.
Definition: Hdf5Util.h:176
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'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:124
hid_t id() const
Query the hid_t value.
Definition: Hdf5Util.h:90
#define FIELD3D_NAMESPACE_OPEN
Definition: ns.h:56