49 #include <H5Epublic.h>
51 #include <boost/tokenizer.hpp>
52 #include <boost/utility.hpp>
71 using namespace Hdf5Util;
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");
91 int k_currentFileVersion[3] =
93 int k_minFileVersion[2] = { 0, 0 };
97 std::vector<std::string> makeUnique(std::vector<std::string> vec)
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());
112 class print : std::unary_function<T, void>
118 void operator()(
const T& x)
const
120 for (
int i = 0; i < indent; i++)
122 std::cout << x << std::endl;
134 bool fileExists(
const std::string &filename)
137 return (stat(filename.c_str(), &statbuf) != -1);
145 void checkFile(
const std::string &filename)
147 if (!fileExists(filename))
149 throw NoSuchFileException(filename);
155 bool isSupportedFileVersion(
const int fileVersion[3],
156 const int minVersion[2])
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] <<
"."
166 stringstream minVersionStr;
167 minVersionStr << minVersion[0] <<
"."
170 if (fileVersion[0] > k_currentFileVersion[0] ||
171 (fileVersion[0] == k_currentFileVersion[0] &&
172 fileVersion[1] > k_currentFileVersion[1])) {
174 " is higher than the current version " +
175 currentVersionStr.str());
179 if (fileVersion[0] < minVersion[0] ||
180 (fileVersion[0] == minVersion[0] &&
181 fileVersion[1] < minVersion[1])) {
183 " is lower than the minimum supported version " +
184 minVersionStr.str());
192 static herr_t localPrintError( hid_t estack_id,
void *stream )
194 printf(
"H5E message -----------------------\n");
195 return H5Eprint2(estack_id, static_cast<FILE*>(stream));
206 std::string Partition::className()
const
208 return k_partitionName;
214 Partition::addScalarLayer(
const Layer &layer)
216 m_scalarLayers.push_back(layer);
222 Partition::addVectorLayer(
const Layer &layer)
224 m_vectorLayers.push_back(layer);
230 Partition::scalarLayer(
const std::string &name)
const
232 for (ScalarLayerList::const_iterator i = m_scalarLayers.begin();
233 i != m_scalarLayers.end(); ++i) {
243 Partition::vectorLayer(
const std::string &name)
const
245 for (VectorLayerList::const_iterator i = m_vectorLayers.begin();
246 i != m_vectorLayers.end(); ++i) {
256 Partition::getScalarLayerNames(std::vector<std::string> &names)
const
260 for (ScalarLayerList::const_iterator i = m_scalarLayers.begin();
261 i != m_scalarLayers.end(); ++i) {
262 names.push_back(i->name);
269 Partition::getVectorLayerNames(std::vector<std::string> &names)
const
273 for (VectorLayerList::const_iterator i = m_vectorLayers.begin();
274 i != m_vectorLayers.end(); ++i) {
275 names.push_back(i->name);
284 : m_file(-1), m_metadata(this)
289 if (getenv(
"DEBUG_HDF")) {
290 cerr <<
"Field3DFile -- HDF5 messages are on" << endl;
291 H5Eset_auto(H5E_DEFAULT, localPrintError, NULL);
293 H5Eset_auto(H5E_DEFAULT, NULL, NULL);
308 const std::string &layerName,
312 for (PartitionList::const_iterator i =
m_partitions.begin();
315 if ((**i).mapping->isIdentical(field->mapping())) {
340 if ((**i).name == partitionName)
352 for (PartitionList::const_iterator i =
m_partitions.begin();
354 if ((**i).name == partitionName)
366 size_t pos = partitionName.rfind(
".");
367 if (pos == partitionName.npos) {
368 return partitionName;
370 return partitionName.substr(0, pos);
381 vector<string> tempNames;
383 for (PartitionList::const_iterator i =
m_partitions.begin();
388 names = makeUnique(tempNames);
395 const string &partitionName)
const
403 part->getScalarLayerNames(names);
406 names = makeUnique(names);
413 const string &partitionName)
const
421 part->getVectorLayerNames(names);
424 names = makeUnique(names);
434 for (PartitionList::const_iterator i =
m_partitions.begin();
436 names.push_back((**i).name);
444 const string &intPartitionName)
const
451 Msg::print(
"getIntScalarLayerNames no partition: " + intPartitionName);
455 part->getScalarLayerNames(names);
462 const string &intPartitionName)
const
469 Msg::print(
"getIntVectorLayerNames no partition: " + intPartitionName);
473 part->getVectorLayerNames(names);
499 if (H5Fclose(
m_file) < 0) {
514 for (PartitionList::const_iterator i =
m_partitions.begin();
516 string name = (**i).name;
517 size_t pos = name.rfind(
".");
518 if (pos != name.npos) {
519 if (name.substr(0, pos) == partitionName) {
534 return partitionName +
"." + boost::lexical_cast<std::string>(i);
542 GroupMembershipMap::const_iterator i= groupMembers.begin();
543 GroupMembershipMap::const_iterator end= groupMembers.end();
545 for (; i != end; ++i) {
546 GroupMembershipMap::iterator foundGroupIter =
592 m_file = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
595 throw NoSuchFileException(filename);
602 if (!isSupportedFileVersion(fileVersion, k_minFileVersion)) {
603 stringstream versionStr;
604 versionStr << fileVersion[0] <<
"."
605 << fileVersion[1] <<
"."
607 throw UnsupportedVersionException(versionStr.str());
611 catch (MissingAttributeException &e) {
616 if (H5Lexists(
m_file,
"field3d_global_metadata", H5P_DEFAULT)) {
619 if (metadataGroup.
id() > 0) {
626 "Unknown error when reading file metadata ");
635 catch (MissingGroupException &e) {
637 throw BadFileHierarchyException(filename);
639 catch (ReadMappingException &e) {
642 throw BadFileHierarchyException(filename);
647 throw BadFileHierarchyException(filename);
651 "Unknown error when reading file hierarchy. ");
652 throw BadFileHierarchyException(filename);
656 catch (NoSuchFileException &e) {
658 +
string(e.what()) );
661 catch (MissingAttributeException &e) {
663 "In file: " + filename +
" - "
664 +
string(e.what()) );
667 catch (UnsupportedVersionException &e) {
669 "In file: " + filename +
" - File version can not be read: "
673 catch (BadFileHierarchyException &e) {
675 "In file: " + filename +
" - Bad file hierarchy. ");
680 "In file: " + filename +
" Unknown exception ");
694 using namespace InputFile;
699 status = H5Literate(
m_file, H5_INDEX_NAME, H5_ITER_NATIVE, NULL,
719 string mappingPath =
"/" + (**i).name +
"/" + k_mappingStr;
723 if (mappingGroup.
id() < 0)
724 throw MissingGroupException((**i).name +
"/" + k_mappingStr);
732 throw ReadMappingException((**i).name);
736 (**i).mapping = mapping;
742 for (PartitionList::const_iterator i =
m_partitions.begin();
755 status = H5Literate(partitionGroup.
id(), H5_INDEX_NAME, H5_ITER_NATIVE,
760 for (std::vector<LayerInfo>::iterator i =
m_layerInfo.begin();
763 std::string parent = i->parentName;
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);
785 const std::string itemName)
799 const std::string &partitionName,
800 const std::string &layerName)
803 if (!
readAttribute(layerGroup,
string(
"components"), 1, components)) {
805 + partitionName +
"/" + layerName);
809 LayerInfo linfo(partitionName,layerName,components);
824 hsize_t num_attrs = H5Aget_num_attrs(metadata_id);
827 for (hsize_t idx=0; idx < num_attrs ; ++idx) {
829 size_t len = H5Aget_name(attrIdx.
id(), 0, NULL);
831 char *name =
new char[len+1];
832 if (H5Aget_name(attrIdx.
id(), len+1, name) > 0) {
836 H5T_class_t typeClass = H5Tget_class(attrType);
838 if (typeClass == H5T_STRING) {
842 "Failed to read metadata " +
string(name));
848 field->metadata().setStrMetadata(name, value);
853 if (H5Sget_simple_extent_ndims(attrSpace) != 1) {
863 H5Sget_simple_extent_dims(attrSpace, dims, NULL);
865 if (typeClass == H5T_INTEGER) {
871 field->metadata().setIntMetadata(name, value);
873 else if (dims[0] == 3){
878 field->metadata().setVecIntMetadata(name, value);
882 "Attribute of size " +
883 boost::lexical_cast<std::string>(dims[0])
884 +
" is not valid for metadata");
887 else if (typeClass == H5T_FLOAT) {
894 field->metadata().setFloatMetadata(name, value);
896 else if (dims[0] == 3){
901 field->metadata().setVecFloatMetadata(name, value);
905 boost::lexical_cast<std::string>(dims[0]) +
906 " is not valid for metadata");
911 +
"' has unsupported data type for metadata");
933 hsize_t num_attrs = H5Aget_num_attrs(metadata_id);
936 for (hsize_t idx=0; idx < num_attrs ; ++idx) {
938 size_t len = H5Aget_name(attrIdx.
id(), 0, NULL);
940 char *name =
new char[len+1];
941 if (H5Aget_name(attrIdx.
id(), len+1, name) > 0) {
945 H5T_class_t typeClass = H5Tget_class(attrType);
947 if (typeClass == H5T_STRING) {
951 "Failed to read metadata " +
string(name));
962 if (H5Sget_simple_extent_ndims(attrSpace) != 1) {
972 H5Sget_simple_extent_dims(attrSpace, dims, NULL);
974 if (typeClass == H5T_INTEGER) {
982 else if (dims[0] == 3){
991 "Attribute of size " +
992 boost::lexical_cast<std::string>(dims[0])
993 +
" is not valid for metadata");
996 else if (typeClass == H5T_FLOAT) {
1005 else if (dims[0] == 3){
1014 boost::lexical_cast<std::string>(dims[0]) +
1015 " is not valid for metadata");
1020 +
"' has unsupported data type for metadata");
1041 if (!H5Lexists(
m_file,
"field3d_group_membership", H5P_DEFAULT)) {
1046 if (memberGroup < 0) {
1050 typedef boost::tokenizer<boost::char_separator<char> > Tok;
1052 hsize_t num_attrs = H5Aget_num_attrs(memberGroup);
1053 if (num_attrs > 0) {
1055 for (hsize_t idx=0; idx < num_attrs ; ++idx) {
1057 size_t len = H5Aget_name(attrIdx.
id(), 0, NULL);
1059 char *name =
new char[len+1];
1060 if (H5Aget_name(attrIdx.
id(), len+1, name) > 0) {
1062 if (
string(name) ==
"is_field3d_group_membership")
1068 H5T_class_t typeClass = H5Tget_class(attrType);
1070 if (typeClass == H5T_STRING) {
1074 "Failed to read group membership data "
1080 boost::char_separator<char> sep(
" :");
1081 Tok tok(value, sep);
1083 for(Tok::iterator beg=tok.begin(); beg!=tok.end();){
1085 string fieldgroup = *beg; ++beg;
1087 new_value += fieldgroup +
" ";
1091 gpMembershipMap[name] = new_value;
1106 namespace InputFile {
1111 const H5L_info_t *linfo,
void *opdata)
1116 status = H5Oget_info_by_name(loc_id, itemName, &infobuf, H5P_DEFAULT);
1122 if (infobuf.type == H5O_TYPE_GROUP) {
1130 if (
string(itemName) !=
"field3d_group_membership" &&
1131 string(itemName) !=
"field3d_global_metadata")
1149 const H5L_info_t *linfo,
void *opdata)
1154 status = H5Oget_info_by_name (loc_id, itemName, &infobuf, H5P_DEFAULT);
1156 if (infobuf.type == H5O_TYPE_GROUP) {
1176 if (classType ==
string(
"field3d_layer"))
1181 catch (MissingAttributeException &e) {
1219 bool success =
true;
1223 hid_t faid = H5Pcreate(H5P_FILE_ACCESS);
1224 H5Pset_libver_bounds(faid, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST);
1229 m_file = H5Fcreate(filename.c_str(),
1230 H5F_ACC_TRUNC, H5P_DEFAULT, faid);
1232 case FailOnExisting:
1233 m_file = H5Fcreate(filename.c_str(),
1234 H5F_ACC_EXCL, H5P_DEFAULT, faid);
1240 throw ErrorCreatingFileException(filename);
1244 k_currentFileVersion[0])) {
1251 catch (ErrorCreatingFileException &e) {
1255 catch (WriteAttributeException &e) {
1257 " - Couldn't add attribute " +
string(e.what()) );
1262 "Unknown error when creating file: " + filename );
1277 if (mappingGroup.
id() < 0)
1278 throw CreateGroupException(k_mappingStr);
1281 throw WriteMappingException(k_mappingStr);
1283 catch (CreateGroupException &e) {
1285 throw WriteMappingException(k_mappingStr);
1294 using namespace Hdf5Util;
1301 for (; i != end; ++i) {
1315 for (; i != end; ++i) {
1329 for (; i != end; ++i) {
1343 for (; i != end; ++i) {
1357 for (; i != end; ++i) {
1375 using namespace Hdf5Util;
1382 for (; i != end; ++i) {
1396 for (; i != end; ++i) {
1410 for (; i != end; ++i) {
1424 for (; i != end; ++i) {
1438 for (; i != end; ++i) {
1460 if (metadataGroup.
id() < 0) {
1464 if (!writeMetadata(metadataGroup.
id())) {
1477 using namespace std;
1478 using namespace Hdf5Util;
1486 "Error creating field3d_group_membership group.");
1490 if (!
writeAttribute(group,
"is_field3d_group_membership",
"1")) {
1492 "Failed to write field3d_group_membership attribute.");
1496 std::map<std::string, std::string>::const_iterator iter =
1498 std::map<std::string, std::string>::const_iterator iEnd =
1501 for (; iter != iEnd; ++iter) {
1504 "Failed to write groupMembership string: "+ iter->first);
1536 for (PartitionList::const_iterator i =
m_partitions.begin();
1538 cout <<
"Name: " << (**i).name << endl;
1540 cout <<
" Mapping: " << (**i).mapping->className() << endl;
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));
1566 field->className());
1572 field->className())) {
1577 return io->write(layerGroup, field);
1586 std::string className;
1588 if (!
readAttribute(mappingGroup, k_mappingTypeAttrName, className)) {
1618 std::string className = mapping->className();
1620 if (!
writeAttribute(mappingGroup, k_mappingTypeAttrName, className)) {
1633 return io->write(mappingGroup, mapping);