51 #include <H5Epublic.h>
53 #include <boost/tokenizer.hpp>
54 #include <boost/utility.hpp>
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");
93 int k_currentFileVersion[3] =
95 int k_minFileVersion[2] = { 0, 0 };
99 std::vector<std::string> makeUnique(std::vector<std::string> vec)
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());
114 class print : std::unary_function<T, void>
120 void operator()(
const T& x)
const
122 for (
int i = 0; i < indent; i++)
124 std::cout << x << std::endl;
139 struct __stat64 statbuf;
140 return (_stat64(filename.c_str(), &statbuf) != -1);
143 return (stat(filename.c_str(), &statbuf) != -1);
152 void checkFile(
const std::string &filename)
156 throw NoSuchFileException(filename);
162 bool isSupportedFileVersion(
const int fileVersion[3],
163 const int minVersion[2])
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] <<
"."
173 stringstream minVersionStr;
174 minVersionStr << minVersion[0] <<
"."
177 if (fileVersion[0] > k_currentFileVersion[0] ||
178 (fileVersion[0] == k_currentFileVersion[0] &&
179 fileVersion[1] > k_currentFileVersion[1])) {
181 " is higher than the current version " +
182 currentVersionStr.str());
186 if (fileVersion[0] < minVersion[0] ||
187 (fileVersion[0] == minVersion[0] &&
188 fileVersion[1] < minVersion[1])) {
190 " is lower than the minimum supported version " +
191 minVersionStr.str());
199 static herr_t localPrintError( hid_t estack_id,
void *stream )
201 printf(
"H5E message -----------------------\n");
202 return H5Eprint2(estack_id, static_cast<FILE*>(stream));
213 std::string Partition::className()
const
215 return k_partitionName;
221 Partition::addScalarLayer(
const Layer &layer)
223 m_scalarLayers.push_back(layer);
229 Partition::addVectorLayer(
const Layer &layer)
231 m_vectorLayers.push_back(layer);
237 Partition::scalarLayer(
const std::string &name)
const
239 for (ScalarLayerList::const_iterator i = m_scalarLayers.begin();
240 i != m_scalarLayers.end(); ++i) {
250 Partition::vectorLayer(
const std::string &name)
const
252 for (VectorLayerList::const_iterator i = m_vectorLayers.begin();
253 i != m_vectorLayers.end(); ++i) {
263 Partition::getScalarLayerNames(std::vector<std::string> &names)
const
267 for (ScalarLayerList::const_iterator i = m_scalarLayers.begin();
268 i != m_scalarLayers.end(); ++i) {
269 names.push_back(i->name);
276 Partition::getVectorLayerNames(std::vector<std::string> &names)
const
280 for (VectorLayerList::const_iterator i = m_vectorLayers.begin();
281 i != m_vectorLayers.end(); ++i) {
282 names.push_back(i->name);
291 : m_file(-1), m_metadata(this)
298 if (getenv(
"DEBUG_HDF")) {
299 cerr <<
"Field3DFileHDF5 -- HDF5 messages are on" << endl;
300 H5Eset_auto(H5E_DEFAULT, localPrintError, NULL);
302 H5Eset_auto(H5E_DEFAULT, NULL, NULL);
317 const std::string & ,
321 for (PartitionList::const_iterator i =
m_partitions.begin();
324 if ((**i).mapping->isIdentical(field->mapping())) {
349 if ((**i).name == partitionName)
361 for (PartitionList::const_iterator i =
m_partitions.begin();
363 if ((**i).name == partitionName)
375 size_t pos = partitionName.rfind(
".");
376 if (pos == partitionName.npos) {
377 return partitionName;
379 return partitionName.substr(0, pos);
390 vector<string> tempNames;
392 for (PartitionList::const_iterator i =
m_partitions.begin();
397 names = makeUnique(tempNames);
404 const string &partitionName)
const
412 part->getScalarLayerNames(names);
415 names = makeUnique(names);
422 const string &partitionName)
const
430 part->getVectorLayerNames(names);
433 names = makeUnique(names);
443 for (PartitionList::const_iterator i =
m_partitions.begin();
445 names.push_back((**i).name);
453 const string &intPartitionName)
const
464 part->getScalarLayerNames(names);
471 const string &intPartitionName)
const
482 part->getVectorLayerNames(names);
510 if (H5Fclose(
m_file) < 0) {
525 for (PartitionList::const_iterator i =
m_partitions.begin();
527 string name = (**i).name;
528 size_t pos = name.rfind(
".");
529 if (pos != name.npos) {
530 if (name.substr(0, pos) == partitionName) {
545 return partitionName +
"." + boost::lexical_cast<std::string>(i);
553 GroupMembershipMap::const_iterator i= groupMembers.begin();
554 GroupMembershipMap::const_iterator end= groupMembers.end();
556 for (; i != end; ++i) {
557 GroupMembershipMap::iterator foundGroupIter =
606 m_file = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
609 throw NoSuchFileException(filename);
616 if (!isSupportedFileVersion(fileVersion, k_minFileVersion)) {
617 stringstream versionStr;
618 versionStr << fileVersion[0] <<
"."
619 << fileVersion[1] <<
"."
621 throw UnsupportedVersionException(versionStr.str());
625 catch (MissingAttributeException &) {
630 if (H5Lexists(
m_file,
"field3d_global_metadata", H5P_DEFAULT)) {
633 if (metadataGroup.
id() > 0) {
640 "Unknown error when reading file metadata ");
649 catch (MissingGroupException &e) {
651 throw BadFileHierarchyException(filename);
653 catch (ReadMappingException &e) {
656 throw BadFileHierarchyException(filename);
661 throw BadFileHierarchyException(filename);
665 "Unknown error when reading file hierarchy. ");
666 throw BadFileHierarchyException(filename);
670 catch (NoSuchFileException &e) {
672 +
string(e.what()) );
675 catch (MissingAttributeException &e) {
677 "In file: " + filename +
" - "
678 +
string(e.what()) );
681 catch (UnsupportedVersionException &e) {
683 "In file: " + filename +
" - File version can not be read: "
687 catch (BadFileHierarchyException &) {
689 "In file: " + filename +
" - Bad file hierarchy. ");
694 "In file: " + filename +
" Unknown exception ");
715 status = H5Literate(
m_file, H5_INDEX_NAME, H5_ITER_NATIVE, NULL,
735 string mappingPath =
"/" + (**i).name +
"/" + k_mappingStr;
739 if (mappingGroup.
id() < 0)
740 throw MissingGroupException((**i).name +
"/" + k_mappingStr);
748 throw ReadMappingException((**i).name);
752 (**i).mapping = mapping;
758 for (PartitionList::const_iterator i =
m_partitions.begin();
771 status = H5Literate(partitionGroup.
id(), H5_INDEX_NAME, H5_ITER_NATIVE,
776 for (std::vector<LayerInfo>::iterator i =
m_layerInfo.begin();
779 std::string parent = i->parentName;
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);
801 const std::string itemName)
815 const std::string &partitionName,
816 const std::string &layerName)
819 if (!
readAttribute(layerGroup,
string(
"components"), 1, components)) {
821 + partitionName +
"/" + layerName);
825 LayerInfo linfo(partitionName,layerName,components);
841 hsize_t num_attrs = H5Aget_num_attrs(metadata_id);
844 for (hsize_t idx=0; idx < num_attrs ; ++idx) {
846 size_t len = H5Aget_name(attrIdx.
id(), 0, NULL);
848 char *name =
new char[len+1];
849 if (H5Aget_name(attrIdx.
id(), len+1, name) > 0) {
853 H5T_class_t typeClass = H5Tget_class(attrType);
855 if (typeClass == H5T_STRING) {
859 "Failed to read metadata " +
string(name));
865 field->metadata().setStrMetadata(name, value);
870 if (H5Sget_simple_extent_ndims(attrSpace) != 1) {
880 H5Sget_simple_extent_dims(attrSpace, dims, NULL);
882 if (typeClass == H5T_INTEGER) {
888 field->metadata().setIntMetadata(name, value);
890 else if (dims[0] == 3){
895 field->metadata().setVecIntMetadata(name, value);
899 "Attribute of size " +
900 boost::lexical_cast<std::string>(dims[0])
901 +
" is not valid for metadata");
904 else if (typeClass == H5T_FLOAT) {
911 field->metadata().setFloatMetadata(name, value);
913 else if (dims[0] == 3){
918 field->metadata().setVecFloatMetadata(name, value);
922 boost::lexical_cast<std::string>(dims[0]) +
923 " is not valid for metadata");
928 +
"' has unsupported data type for metadata");
951 hsize_t num_attrs = H5Aget_num_attrs(metadata_id);
954 for (hsize_t idx=0; idx < num_attrs ; ++idx) {
956 size_t len = H5Aget_name(attrIdx.
id(), 0, NULL);
958 char *name =
new char[len+1];
959 if (H5Aget_name(attrIdx.
id(), len+1, name) > 0) {
963 H5T_class_t typeClass = H5Tget_class(attrType);
965 if (typeClass == H5T_STRING) {
969 "Failed to read metadata " +
string(name));
980 if (H5Sget_simple_extent_ndims(attrSpace) != 1) {
990 H5Sget_simple_extent_dims(attrSpace, dims, NULL);
992 if (typeClass == H5T_INTEGER) {
1000 else if (dims[0] == 3){
1009 "Attribute of size " +
1010 boost::lexical_cast<std::string>(dims[0])
1011 +
" is not valid for metadata");
1014 else if (typeClass == H5T_FLOAT) {
1023 else if (dims[0] == 3){
1032 boost::lexical_cast<std::string>(dims[0]) +
1033 " is not valid for metadata");
1038 +
"' has unsupported data type for metadata");
1061 if (!H5Lexists(
m_file,
"field3d_group_membership", H5P_DEFAULT)) {
1066 if (memberGroup < 0) {
1070 typedef boost::tokenizer<boost::char_separator<char> > Tok;
1072 hsize_t num_attrs = H5Aget_num_attrs(memberGroup);
1073 if (num_attrs > 0) {
1075 for (hsize_t idx=0; idx < num_attrs ; ++idx) {
1077 size_t len = H5Aget_name(attrIdx.
id(), 0, NULL);
1079 char *name =
new char[len+1];
1080 if (H5Aget_name(attrIdx.
id(), len+1, name) > 0) {
1082 if (
string(name) ==
"is_field3d_group_membership")
1088 H5T_class_t typeClass = H5Tget_class(attrType);
1090 if (typeClass == H5T_STRING) {
1094 "Failed to read group membership data "
1100 boost::char_separator<char> sep(
" :");
1101 Tok tok(value, sep);
1103 for(Tok::iterator beg=tok.begin(); beg!=tok.end();){
1105 string fieldgroup = *beg; ++beg;
1107 new_value += fieldgroup +
" ";
1111 gpMembershipMap[name] = new_value;
1131 const H5L_info_t * ,
void *opdata)
1138 status = H5Oget_info_by_name(loc_id, itemName, &infobuf, H5P_DEFAULT);
1144 if (infobuf.type == H5O_TYPE_GROUP) {
1152 if (
string(itemName) !=
"field3d_group_membership" &&
1153 string(itemName) !=
"field3d_global_metadata")
1171 const H5L_info_t * ,
void *opdata)
1178 status = H5Oget_info_by_name (loc_id, itemName, &infobuf, H5P_DEFAULT);
1180 if (infobuf.type == H5O_TYPE_GROUP) {
1200 if (classType ==
string(
"field3d_layer"))
1205 catch (MissingAttributeException &) {
1245 bool success =
true;
1249 hid_t faid = H5Pcreate(H5P_FILE_ACCESS);
1250 H5Pset_libver_bounds(faid, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST);
1255 m_file = H5Fcreate(filename.c_str(),
1256 H5F_ACC_TRUNC, H5P_DEFAULT, faid);
1258 case FailOnExisting:
1259 m_file = H5Fcreate(filename.c_str(),
1260 H5F_ACC_EXCL, H5P_DEFAULT, faid);
1266 throw ErrorCreatingFileException(filename);
1270 k_currentFileVersion[0])) {
1277 catch (ErrorCreatingFileException &e) {
1281 catch (WriteAttributeException &e) {
1283 " - Couldn't add attribute " +
string(e.what()) );
1288 "Unknown error when creating file: " + filename );
1305 if (mappingGroup.
id() < 0)
1306 throw CreateGroupException(k_mappingStr);
1309 throw WriteMappingException(k_mappingStr);
1311 catch (CreateGroupException &e) {
1313 throw WriteMappingException(k_mappingStr);
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) {
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) {
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) {
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) {
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) {
1406 FieldMetadata::StrMetadata::const_iterator i =
1408 FieldMetadata::StrMetadata::const_iterator end =
1410 for (; i != end; ++i) {
1420 FieldMetadata::IntMetadata::const_iterator i =
1422 FieldMetadata::IntMetadata::const_iterator end =
1424 for (; i != end; ++i) {
1434 FieldMetadata::FloatMetadata::const_iterator i =
1436 FieldMetadata::FloatMetadata::const_iterator end =
1438 for (; i != end; ++i) {
1448 FieldMetadata::VecIntMetadata::const_iterator i =
1450 FieldMetadata::VecIntMetadata::const_iterator end =
1452 for (; i != end; ++i) {
1462 FieldMetadata::VecFloatMetadata::const_iterator i =
1464 FieldMetadata::VecFloatMetadata::const_iterator end =
1466 for (; i != end; ++i) {
1489 if (metadataGroup.
id() < 0) {
1493 if (!writeMetadata(metadataGroup.
id())) {
1506 using namespace std;
1517 "Error creating field3d_group_membership group.");
1521 if (!
writeAttribute(group,
"is_field3d_group_membership",
"1")) {
1523 "Failed to write field3d_group_membership attribute.");
1527 std::map<std::string, std::string>::const_iterator iter =
1529 std::map<std::string, std::string>::const_iterator iEnd =
1532 for (; iter != iEnd; ++iter) {
1535 "Failed to write groupMembership string: "+ iter->first);
1567 for (PartitionList::const_iterator i =
m_partitions.begin();
1569 cout <<
"Name: " << (**i).name << endl;
1571 cout <<
" Mapping: " << (**i).mapping->className() << endl;
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));
1597 field->className());
1603 field->className())) {
1608 return io->write(layerGroup, field);
1617 std::string className;
1619 if (!
readAttribute(mappingGroup, k_mappingTypeAttrName, className)) {
1649 std::string className = mapping->className();
1651 if (!
writeAttribute(mappingGroup, k_mappingTypeAttrName, className)) {
1664 return io->write(mappingGroup, mapping);