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