Field3D
|
00001 //----------------------------------------------------------------------------// 00002 00003 /* 00004 * Copyright (c) 2009 Sony Pictures Imageworks Inc 00005 * 00006 * All rights reserved. 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions 00010 * are met: 00011 * 00012 * Redistributions of source code must retain the above copyright 00013 * notice, this list of conditions and the following disclaimer. 00014 * Redistributions in binary form must reproduce the above copyright 00015 * notice, this list of conditions and the following disclaimer in the 00016 * documentation and/or other materials provided with the 00017 * distribution. Neither the name of Sony Pictures Imageworks nor the 00018 * names of its contributors may be used to endorse or promote 00019 * products derived from this software without specific prior written 00020 * permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00023 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00024 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00025 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00026 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00027 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00028 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00029 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00030 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 00031 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00032 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 00033 * OF THE POSSIBILITY OF SUCH DAMAGE. 00034 */ 00035 00036 //----------------------------------------------------------------------------// 00037 00043 //----------------------------------------------------------------------------// 00044 00045 #include <sys/stat.h> 00046 #include <unistd.h> 00047 00048 #include <hdf5.h> 00049 #include <H5Epublic.h> 00050 00051 #include <boost/tokenizer.hpp> 00052 #include <boost/utility.hpp> 00053 00054 #include "Field3DFile.h" 00055 #include "Field.h" 00056 #include "ClassFactory.h" 00057 00058 //----------------------------------------------------------------------------// 00059 00060 using namespace std; 00061 00062 //----------------------------------------------------------------------------// 00063 00064 FIELD3D_NAMESPACE_OPEN 00065 00066 //----------------------------------------------------------------------------// 00067 // Field3D namespaces 00068 //----------------------------------------------------------------------------// 00069 00070 using namespace Exc; 00071 using namespace Hdf5Util; 00072 using namespace File; 00073 00074 //----------------------------------------------------------------------------// 00075 // Local namespace 00076 //----------------------------------------------------------------------------// 00077 00078 namespace { 00079 00080 // Strings used only in this file -------------------------------------------- 00081 00082 const std::string k_mappingStr("mapping"); 00083 const std::string k_partitionName("partition"); 00084 const std::string k_versionAttrName("version_number"); 00085 const std::string k_classNameAttrName("class_name"); 00086 const std::string k_mappingTypeAttrName("mapping_type"); 00087 00090 00091 int k_currentFileVersion[3] = 00092 { FIELD3D_MAJOR_VER, FIELD3D_MINOR_VER, FIELD3D_MICRO_VER }; 00093 int k_minFileVersion[2] = { 0, 0 }; 00094 00095 // Function objects used only in this file ----------------------------------- 00096 00097 std::vector<std::string> makeUnique(std::vector<std::string> vec) 00098 { 00099 std::vector<string> ret; 00100 std::sort(vec.begin(), vec.end()); 00101 std::vector<std::string>::iterator newEnd = 00102 std::unique(vec.begin(), vec.end()); 00103 ret.resize(std::distance(vec.begin(), newEnd)); 00104 std::copy(vec.begin(), newEnd, ret.begin()); 00105 return ret; 00106 } 00107 00108 //----------------------------------------------------------------------------// 00109 00111 template <class T> 00112 class print : std::unary_function<T, void> 00113 { 00114 public: 00115 print(int indentAmt) 00116 : indent(indentAmt) 00117 { } 00118 void operator()(const T& x) const 00119 { 00120 for (int i = 0; i < indent; i++) 00121 std::cout << " "; 00122 std::cout << x << std::endl; 00123 } 00124 int indent; 00125 }; 00126 00127 //----------------------------------------------------------------------------// 00128 00134 bool fileExists(const std::string &filename) 00135 { 00136 struct stat statbuf; 00137 return (stat(filename.c_str(), &statbuf) != -1); 00138 } 00139 00145 void checkFile(const std::string &filename) 00146 { 00147 if (!fileExists(filename)) 00148 { 00149 throw NoSuchFileException(filename); 00150 } 00151 } 00152 00153 //----------------------------------------------------------------------------// 00154 00155 bool isSupportedFileVersion(const int fileVersion[3], 00156 const int minVersion[2]) 00157 { 00158 stringstream currentVersionStr; 00159 currentVersionStr << k_currentFileVersion[0] << "." 00160 << k_currentFileVersion[1] << "." 00161 << k_currentFileVersion[2]; 00162 stringstream fileVersionStr; 00163 fileVersionStr << fileVersion[0] << "." 00164 << fileVersion[1] << "." 00165 << fileVersion[2]; 00166 stringstream minVersionStr; 00167 minVersionStr << minVersion[0] << "." 00168 << minVersion[1]; 00169 00170 if (fileVersion[0] > k_currentFileVersion[0] || 00171 (fileVersion[0] == k_currentFileVersion[0] && 00172 fileVersion[1] > k_currentFileVersion[1])) { 00173 Msg::print(Msg::SevWarning, "File version " + fileVersionStr.str() + 00174 " is higher than the current version " + 00175 currentVersionStr.str()); 00176 return true; 00177 } 00178 00179 if (fileVersion[0] < minVersion[0] || 00180 (fileVersion[0] == minVersion[0] && 00181 fileVersion[1] < minVersion[1])) { 00182 Msg::print(Msg::SevWarning, "File version " + fileVersionStr.str() + 00183 " is lower than the minimum supported version " + 00184 minVersionStr.str()); 00185 return false; 00186 } 00187 return true; 00188 } 00189 00190 //----------------------------------------------------------------------------// 00191 00192 static herr_t localPrintError( hid_t estack_id, void *stream ) 00193 { 00194 printf("H5E message -----------------------\n"); 00195 return H5Eprint2(estack_id, static_cast<FILE*>(stream)); 00196 } 00197 00198 //----------------------------------------------------------------------------// 00199 00200 } // end of local namespace 00201 00202 //----------------------------------------------------------------------------// 00203 // Partition implementations 00204 //----------------------------------------------------------------------------// 00205 00206 std::string Partition::className() const 00207 { 00208 return k_partitionName; 00209 } 00210 00211 //----------------------------------------------------------------------------// 00212 00213 void 00214 Partition::addScalarLayer(const Layer &layer) 00215 { 00216 m_scalarLayers.push_back(layer); 00217 } 00218 00219 //----------------------------------------------------------------------------// 00220 00221 void 00222 Partition::addVectorLayer(const Layer &layer) 00223 { 00224 m_vectorLayers.push_back(layer); 00225 } 00226 00227 //----------------------------------------------------------------------------// 00228 00229 const Layer* 00230 Partition::scalarLayer(const std::string &name) const 00231 { 00232 for (ScalarLayerList::const_iterator i = m_scalarLayers.begin(); 00233 i != m_scalarLayers.end(); ++i) { 00234 if (i->name == name) 00235 return &(*i); 00236 } 00237 return NULL; 00238 } 00239 00240 //----------------------------------------------------------------------------// 00241 00242 const Layer* 00243 Partition::vectorLayer(const std::string &name) const 00244 { 00245 for (VectorLayerList::const_iterator i = m_vectorLayers.begin(); 00246 i != m_vectorLayers.end(); ++i) { 00247 if (i->name == name) 00248 return &(*i); 00249 } 00250 return NULL; 00251 } 00252 00253 //----------------------------------------------------------------------------// 00254 00255 void 00256 Partition::getScalarLayerNames(std::vector<std::string> &names) const 00257 { 00258 // We don't want to do names.clear() here, since this gets called 00259 // inside some loops that want to accumulate names. 00260 for (ScalarLayerList::const_iterator i = m_scalarLayers.begin(); 00261 i != m_scalarLayers.end(); ++i) { 00262 names.push_back(i->name); 00263 } 00264 } 00265 00266 //----------------------------------------------------------------------------// 00267 00268 void 00269 Partition::getVectorLayerNames(std::vector<std::string> &names) const 00270 { 00271 // We don't want to do names.clear() here, since this gets called 00272 // inside some loops that want to accumulate names. 00273 for (VectorLayerList::const_iterator i = m_vectorLayers.begin(); 00274 i != m_vectorLayers.end(); ++i) { 00275 names.push_back(i->name); 00276 } 00277 } 00278 00279 //----------------------------------------------------------------------------// 00280 // Field3DFileBase implementations 00281 //----------------------------------------------------------------------------// 00282 00283 Field3DFileBase::Field3DFileBase() 00284 : m_file(-1), m_metadata(this) 00285 { 00286 // Suppressing HDF error messages 00287 // Explanation about the function for the error stack is here: 00288 // http://www.hdfgroup.org/HDF5/doc/RM/RM_H5E.html#Error-SetAuto2 00289 if (getenv("DEBUG_HDF")) { 00290 cerr << "Field3DFile -- HDF5 messages are on" << endl; 00291 H5Eset_auto(H5E_DEFAULT, localPrintError, NULL); 00292 } else { 00293 H5Eset_auto(H5E_DEFAULT, NULL, NULL); 00294 } 00295 } 00296 00297 //----------------------------------------------------------------------------// 00298 00299 Field3DFileBase::~Field3DFileBase() 00300 { 00301 close(); 00302 } 00303 00304 //----------------------------------------------------------------------------// 00305 00306 std::string 00307 Field3DFileBase::intPartitionName(const std::string &partitionName, 00308 const std::string &layerName, 00309 FieldRes::Ptr field) 00310 { 00311 // Loop over existing partitions and see if there's a matching mapping 00312 for (PartitionList::const_iterator i = m_partitions.begin(); 00313 i != m_partitions.end(); ++i) { 00314 if (removeUniqueId((**i).name) == partitionName) { 00315 if ((**i).mapping->isIdentical(field->mapping())) { 00316 return (**i).name; 00317 } 00318 } 00319 } 00320 00321 // If there was no previously matching name, then make a new one 00322 00323 int nextIdx = -1; 00324 if (m_partitionCount.find(partitionName) != m_partitionCount.end()) { 00325 nextIdx = ++m_partitionCount[partitionName]; 00326 } else { 00327 nextIdx = 0; 00328 m_partitionCount[partitionName] = 0; 00329 } 00330 00331 return makeIntPartitionName(partitionName, nextIdx); 00332 } 00333 00334 //----------------------------------------------------------------------------// 00335 00336 Partition::Ptr Field3DFileBase::partition(const string &partitionName) 00337 { 00338 for (PartitionList::iterator i = m_partitions.begin(); 00339 i != m_partitions.end(); ++i) { 00340 if ((**i).name == partitionName) 00341 return *i; 00342 } 00343 00344 return Partition::Ptr(); 00345 } 00346 00347 //----------------------------------------------------------------------------// 00348 00349 Partition::Ptr 00350 Field3DFileBase::partition(const string &partitionName) const 00351 { 00352 for (PartitionList::const_iterator i = m_partitions.begin(); 00353 i != m_partitions.end(); ++i) { 00354 if ((**i).name == partitionName) 00355 return *i; 00356 } 00357 00358 return Partition::Ptr(); 00359 } 00360 00361 //----------------------------------------------------------------------------// 00362 00363 std::string 00364 Field3DFileBase::removeUniqueId(const std::string &partitionName) const 00365 { 00366 size_t pos = partitionName.rfind("."); 00367 if (pos == partitionName.npos) { 00368 return partitionName; 00369 } else { 00370 return partitionName.substr(0, pos); 00371 } 00372 } 00373 00374 //----------------------------------------------------------------------------// 00375 00376 void 00377 Field3DFileBase::getPartitionNames(vector<string> &names) const 00378 { 00379 names.clear(); 00380 00381 vector<string> tempNames; 00382 00383 for (PartitionList::const_iterator i = m_partitions.begin(); 00384 i != m_partitions.end(); ++i) { 00385 tempNames.push_back(removeUniqueId((**i).name)); 00386 } 00387 00388 names = makeUnique(tempNames); 00389 } 00390 00391 //----------------------------------------------------------------------------// 00392 00393 void 00394 Field3DFileBase::getScalarLayerNames(vector<string> &names, 00395 const string &partitionName) const 00396 { 00397 names.clear(); 00398 00399 for (int i = 0; i < numIntPartitions(partitionName); i++) { 00400 string internalName = makeIntPartitionName(partitionName, i); 00401 Partition::Ptr part = partition(internalName); 00402 if (part) 00403 part->getScalarLayerNames(names); 00404 } 00405 00406 names = makeUnique(names); 00407 } 00408 00409 //----------------------------------------------------------------------------// 00410 00411 void 00412 Field3DFileBase::getVectorLayerNames(vector<string> &names, 00413 const string &partitionName) const 00414 { 00415 names.clear(); 00416 00417 for (int i = 0; i < numIntPartitions(partitionName); i++) { 00418 string internalName = makeIntPartitionName(partitionName, i); 00419 Partition::Ptr part = partition(internalName); 00420 if (part) 00421 part->getVectorLayerNames(names); 00422 } 00423 00424 names = makeUnique(names); 00425 } 00426 00427 //----------------------------------------------------------------------------// 00428 00429 void 00430 Field3DFileBase::getIntPartitionNames(vector<string> &names) const 00431 { 00432 names.clear(); 00433 00434 for (PartitionList::const_iterator i = m_partitions.begin(); 00435 i != m_partitions.end(); ++i) { 00436 names.push_back((**i).name); 00437 } 00438 } 00439 00440 //----------------------------------------------------------------------------// 00441 00442 void 00443 Field3DFileBase::getIntScalarLayerNames(vector<string> &names, 00444 const string &intPartitionName) const 00445 { 00446 names.clear(); 00447 00448 Partition::Ptr part = partition(intPartitionName); 00449 00450 if (!part) { 00451 Msg::print("getIntScalarLayerNames no partition: " + intPartitionName); 00452 return; 00453 } 00454 00455 part->getScalarLayerNames(names); 00456 } 00457 00458 //----------------------------------------------------------------------------// 00459 00460 void 00461 Field3DFileBase::getIntVectorLayerNames(vector<string> &names, 00462 const string &intPartitionName) const 00463 { 00464 names.clear(); 00465 00466 Partition::Ptr part = partition(intPartitionName); 00467 00468 if (!part) { 00469 Msg::print("getIntVectorLayerNames no partition: " + intPartitionName); 00470 return; 00471 } 00472 00473 part->getVectorLayerNames(names); 00474 } 00475 00476 //----------------------------------------------------------------------------// 00477 00478 void Field3DFileBase::clear() 00479 { 00480 closeInternal(); 00481 m_partitions.clear(); 00482 m_groupMembership.clear(); 00483 } 00484 00485 //----------------------------------------------------------------------------// 00486 00487 bool Field3DFileBase::close() 00488 { 00489 closeInternal(); 00490 00491 return true; 00492 } 00493 00494 //----------------------------------------------------------------------------// 00495 00496 void Field3DFileBase::closeInternal() 00497 { 00498 if (m_file != -1) { 00499 if (H5Fclose(m_file) < 0) { 00500 Msg::print(Msg::SevWarning, "Failed to close hdf5 file handle"); 00501 return; 00502 } 00503 m_file = -1; 00504 } 00505 } 00506 00507 //----------------------------------------------------------------------------// 00508 00509 int 00510 Field3DFileBase::numIntPartitions(const std::string &partitionName) const 00511 { 00512 int count = 0; 00513 00514 for (PartitionList::const_iterator i = m_partitions.begin(); 00515 i != m_partitions.end(); ++i) { 00516 string name = (**i).name; 00517 size_t pos = name.rfind("."); 00518 if (pos != name.npos) { 00519 if (name.substr(0, pos) == partitionName) { 00520 count++; 00521 } 00522 } 00523 } 00524 00525 return count; 00526 } 00527 00528 //----------------------------------------------------------------------------// 00529 00530 string 00531 Field3DFileBase::makeIntPartitionName(const std::string &partitionName, 00532 int i) const 00533 { 00534 return partitionName + "." + boost::lexical_cast<std::string>(i); 00535 } 00536 00537 //----------------------------------------------------------------------------// 00538 00539 void 00540 Field3DFileBase::addGroupMembership(const GroupMembershipMap& groupMembers) 00541 { 00542 GroupMembershipMap::const_iterator i= groupMembers.begin(); 00543 GroupMembershipMap::const_iterator end= groupMembers.end(); 00544 00545 for (; i != end; ++i) { 00546 GroupMembershipMap::iterator foundGroupIter = 00547 m_groupMembership.find(i->first); 00548 if (foundGroupIter != m_groupMembership.end()){ 00549 std::string value = m_groupMembership[i->first] + i->second; 00550 m_groupMembership[i->first] = value; 00551 } else { 00552 m_groupMembership[i->first] = i->second; 00553 } 00554 } 00555 } 00556 00557 //----------------------------------------------------------------------------// 00558 // Field3DInputFile implementations 00559 //----------------------------------------------------------------------------// 00560 00561 Field3DInputFile::Field3DInputFile() 00562 { 00563 // Empty 00564 } 00565 00566 //----------------------------------------------------------------------------// 00567 00568 Field3DInputFile::~Field3DInputFile() 00569 { 00570 clear(); 00571 } 00572 00573 //----------------------------------------------------------------------------// 00574 00575 bool Field3DInputFile::open(const string &filename) 00576 { 00577 clear(); 00578 00579 bool success = true; 00580 00581 m_filename = filename; 00582 00583 try { 00584 00585 string version; 00586 00587 // Throws exceptions if the file doesn't exist. 00588 // This was added because H5Fopen prints out a lot of junk 00589 // to the terminal. 00590 checkFile(filename); 00591 00592 m_file = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT); 00593 00594 if (m_file < 0) 00595 throw NoSuchFileException(filename); 00596 00597 int fileVersion[3]; 00598 try { 00599 if (!readAttribute(m_file, k_versionAttrName, 3, fileVersion[0])) { 00600 //Msg::print(Msg::SevWarning, "Missing version_number attribute"); 00601 } else { 00602 if (!isSupportedFileVersion(fileVersion, k_minFileVersion)) { 00603 stringstream versionStr; 00604 versionStr << fileVersion[0] << "." 00605 << fileVersion[1] << "." 00606 << fileVersion[2]; 00607 throw UnsupportedVersionException(versionStr.str()); 00608 } 00609 } 00610 } 00611 catch (MissingAttributeException &e) { 00612 //Msg::print(Msg::SevWarning, "Missing version_number attribute"); 00613 } 00614 00615 try { 00616 if (H5Lexists(m_file, "field3d_global_metadata", H5P_DEFAULT)) { 00617 // read the metadata 00618 H5ScopedGopen metadataGroup(m_file, "field3d_global_metadata"); 00619 if (metadataGroup.id() > 0) { 00620 readMetadata(metadataGroup.id()); 00621 } 00622 } 00623 } 00624 catch (...) { 00625 Msg::print(Msg::SevWarning, 00626 "Unknown error when reading file metadata "); 00627 //throw BadFileHierarchyException(filename); 00628 } 00629 00630 try { 00631 if (!readPartitionAndLayerInfo()) { 00632 success = false; 00633 } 00634 } 00635 catch (MissingGroupException &e) { 00636 Msg::print(Msg::SevWarning, "Missing group: " + string(e.what())); 00637 throw BadFileHierarchyException(filename); 00638 } 00639 catch (ReadMappingException &e) { 00640 Msg::print(Msg::SevWarning, "Couldn't read mapping for partition: " 00641 + string(e.what())); 00642 throw BadFileHierarchyException(filename); 00643 } 00644 catch (Exception &e) { 00645 Msg::print(Msg::SevWarning, "Unknown error when reading file hierarchy: " 00646 + string(e.what())); 00647 throw BadFileHierarchyException(filename); 00648 } 00649 catch (...) { 00650 Msg::print(Msg::SevWarning, 00651 "Unknown error when reading file hierarchy. "); 00652 throw BadFileHierarchyException(filename); 00653 } 00654 00655 } 00656 catch (NoSuchFileException &e) { 00657 Msg::print(Msg::SevWarning, "Couldn't open file: " 00658 + string(e.what()) ); 00659 success = false; 00660 } 00661 catch (MissingAttributeException &e) { 00662 Msg::print(Msg::SevWarning, 00663 "In file: " + filename + " - " 00664 + string(e.what()) ); 00665 success = false; 00666 } 00667 catch (UnsupportedVersionException &e) { 00668 Msg::print(Msg::SevWarning, 00669 "In file: " + filename + " - File version can not be read: " 00670 + string(e.what())); 00671 success = false; 00672 } 00673 catch (BadFileHierarchyException &e) { 00674 Msg::print(Msg::SevWarning, 00675 "In file: " + filename + " - Bad file hierarchy. "); 00676 success = false; 00677 } 00678 catch (...) { 00679 Msg::print(Msg::SevWarning, 00680 "In file: " + filename + " Unknown exception "); 00681 success = false; 00682 } 00683 00684 if (!success) 00685 close(); 00686 00687 return success; 00688 } 00689 00690 //----------------------------------------------------------------------------// 00691 00692 bool Field3DInputFile::readPartitionAndLayerInfo() 00693 { 00694 using namespace InputFile; 00695 00696 // First, find the partitions --- 00697 00698 herr_t status; 00699 status = H5Literate(m_file, H5_INDEX_NAME, H5_ITER_NATIVE, NULL, 00700 &parsePartitions, this); 00701 00702 // Get the partition names to store 00703 m_partitions.clear(); 00704 00705 for (size_t i=0; i < m_partitionNames.size(); i++) { 00706 Partition::Ptr part(new Partition); 00707 part->name = m_partitionNames[i]; 00708 m_partitions.push_back(part); 00709 } 00710 00711 // For each partition, find its mapping --- 00712 00713 for (PartitionList::iterator i = m_partitions.begin(); 00714 i != m_partitions.end(); ++i) { 00715 00716 // Open the partition 00717 H5ScopedGopen partitionGroup(m_file, (**i).name); 00718 00719 string mappingPath = "/" + (**i).name + "/" + k_mappingStr; 00720 00721 // Open up the mapping group 00722 H5ScopedGopen mappingGroup(m_file, mappingPath); 00723 if (mappingGroup.id() < 0) 00724 throw MissingGroupException((**i).name + "/" + k_mappingStr); 00725 00726 // Try to build a mapping from it 00727 FieldMapping::Ptr mapping; 00728 00729 mapping = readFieldMapping(mappingGroup.id()); 00730 if (!mapping) { 00731 Msg::print(Msg::SevWarning, "Got a null pointer when reading mapping"); 00732 throw ReadMappingException((**i).name); 00733 } 00734 00735 // Attach the mapping to the partition 00736 (**i).mapping = mapping; 00737 00738 } 00739 00740 // ... And then find its layers --- 00741 00742 for (PartitionList::const_iterator i = m_partitions.begin(); 00743 i != m_partitions.end(); ++i) { 00744 00745 // Open the partition 00746 H5ScopedGopen partitionGroup(m_file, (**i).name); 00747 00748 // Set up the info struct for the callback 00749 ParseLayersInfo info; 00750 info.file = this; 00751 info.partitionName = (**i).name; 00752 00753 m_layerInfo.clear(); 00754 00755 status = H5Literate(partitionGroup.id(), H5_INDEX_NAME, H5_ITER_NATIVE, 00756 NULL, &parseLayers, &info); 00757 00758 //set the layer information on the partitions here 00759 00760 for (std::vector<LayerInfo>::iterator i = m_layerInfo.begin(); 00761 i != m_layerInfo.end(); i++) { 00762 00763 std::string parent = i->parentName; 00764 00765 Partition::Ptr part = partition(parent); 00766 00767 Layer layer; 00768 layer.name = i->name; 00769 layer.parent = i->parentName; 00770 if (i->components == 1) { 00771 part->addScalarLayer(layer); 00772 } else if (i->components == 3) { 00773 part->addVectorLayer(layer); 00774 } 00775 } 00776 00777 } 00778 00779 return true; 00780 } 00781 00782 //----------------------------------------------------------------------------// 00783 00784 herr_t Field3DInputFile::parsePartition(hid_t loc_id, 00785 const std::string itemName) 00786 { 00787 // Add the partition --- 00788 00789 m_partitionNames.push_back(string(itemName)); 00790 return 0; 00791 } 00792 00793 //----------------------------------------------------------------------------// 00794 00798 herr_t Field3DInputFile::parseLayer(hid_t layerGroup, 00799 const std::string &partitionName, 00800 const std::string &layerName) 00801 { 00802 int components; 00803 if (!readAttribute(layerGroup, string("components"), 1, components)) { 00804 Msg::print(Msg::SevWarning, "Couldn't read components attribute for layer " 00805 + partitionName + "/" + layerName); 00806 return 0; 00807 } 00808 00809 LayerInfo linfo(partitionName,layerName,components); 00810 00811 m_layerInfo.push_back(linfo); 00812 00813 return 0; 00814 } 00815 00816 //----------------------------------------------------------------------------// 00817 00819 bool 00820 Field3DInputFile:: 00821 readMetadata(hid_t metadata_id, FieldBase::Ptr field) const 00822 { 00823 00824 hsize_t num_attrs = H5Aget_num_attrs(metadata_id); 00825 00826 if (num_attrs > 0) { 00827 for (hsize_t idx=0; idx < num_attrs ; ++idx) { 00828 H5ScopedAopenIdx attrIdx(metadata_id, idx); 00829 size_t len = H5Aget_name(attrIdx.id(), 0, NULL); 00830 if (len > 0) { 00831 char *name = new char[len+1]; 00832 if (H5Aget_name(attrIdx.id(), len+1, name) > 0) { 00833 H5ScopedAopen attr(metadata_id, name, H5P_DEFAULT); 00834 H5ScopedAget_space attrSpace(attr); 00835 H5ScopedAget_type attrType(attr); 00836 H5T_class_t typeClass = H5Tget_class(attrType); 00837 00838 if (typeClass == H5T_STRING) { 00839 string value; 00840 if (!readAttribute(metadata_id, name, value)) { 00841 Msg::print(Msg::SevWarning, 00842 "Failed to read metadata " + string(name)); 00843 if (name) { 00844 delete[] name; 00845 } 00846 continue; 00847 } 00848 field->metadata().setStrMetadata(name, value); 00849 00850 } 00851 else { 00852 00853 if (H5Sget_simple_extent_ndims(attrSpace) != 1) { 00854 Msg::print(Msg::SevWarning, "Bad attribute rank for attribute " 00855 + string(name)); 00856 if (name) { 00857 delete[] name; 00858 } 00859 continue; 00860 } 00861 00862 hsize_t dims[1]; 00863 H5Sget_simple_extent_dims(attrSpace, dims, NULL); 00864 00865 if (typeClass == H5T_INTEGER) { 00866 if (dims[0] == 1){ 00867 int value; 00868 if (!readAttribute(metadata_id, name, dims[0], value)) 00869 Msg::print(Msg::SevWarning, "Failed to read metadata " 00870 + string(name)); 00871 field->metadata().setIntMetadata(name, value); 00872 } 00873 else if (dims[0] == 3){ 00874 V3i value; 00875 if (!readAttribute(metadata_id, name, dims[0], value.x)) 00876 Msg::print(Msg::SevWarning, "Failed to read metadata " + 00877 string(name) ); 00878 field->metadata().setVecIntMetadata(name, value); 00879 } 00880 else { 00881 Msg::print(Msg::SevWarning, 00882 "Attribute of size " + 00883 boost::lexical_cast<std::string>(dims[0]) 00884 + " is not valid for metadata"); 00885 } 00886 } 00887 else if (typeClass == H5T_FLOAT) { 00888 if (dims[0] == 1){ 00889 float value; 00890 if (!readAttribute(metadata_id, name, dims[0], value)) 00891 Msg::print(Msg::SevWarning, "Failed to read metadata " + 00892 string(name) ); 00893 00894 field->metadata().setFloatMetadata(name, value); 00895 } 00896 else if (dims[0] == 3){ 00897 V3f value; 00898 if (!readAttribute(metadata_id, name, dims[0], value.x)) 00899 Msg::print(Msg::SevWarning, "Failed to read metadata "+ 00900 string(name) ); 00901 field->metadata().setVecFloatMetadata(name, value); 00902 } 00903 else { 00904 Msg::print(Msg::SevWarning, "Attribute of size " + 00905 boost::lexical_cast<std::string>(dims[0]) + 00906 " is not valid for metadata"); 00907 } 00908 } 00909 else { 00910 Msg::print(Msg::SevWarning, "Attribute '" + string(name) + 00911 + "' has unsupported data type for metadata"); 00912 00913 } 00914 } 00915 } 00916 if (name) { 00917 delete[] name; 00918 } 00919 } 00920 } 00921 } 00922 00923 return true; 00924 } 00925 00926 //----------------------------------------------------------------------------// 00927 00929 bool 00930 Field3DInputFile::readMetadata(hid_t metadata_id) 00931 { 00932 00933 hsize_t num_attrs = H5Aget_num_attrs(metadata_id); 00934 00935 if (num_attrs > 0) { 00936 for (hsize_t idx=0; idx < num_attrs ; ++idx) { 00937 H5ScopedAopenIdx attrIdx(metadata_id, idx); 00938 size_t len = H5Aget_name(attrIdx.id(), 0, NULL); 00939 if (len > 0) { 00940 char *name = new char[len+1]; 00941 if (H5Aget_name(attrIdx.id(), len+1, name) > 0) { 00942 H5ScopedAopen attr(metadata_id, name, H5P_DEFAULT); 00943 H5ScopedAget_space attrSpace(attr); 00944 H5ScopedAget_type attrType(attr); 00945 H5T_class_t typeClass = H5Tget_class(attrType); 00946 00947 if (typeClass == H5T_STRING) { 00948 string value; 00949 if (!readAttribute(metadata_id, name, value)) { 00950 Msg::print(Msg::SevWarning, 00951 "Failed to read metadata " + string(name)); 00952 if (name) { 00953 delete[] name; 00954 } 00955 continue; 00956 } 00957 metadata().setStrMetadata(name, value); 00958 00959 } 00960 else { 00961 00962 if (H5Sget_simple_extent_ndims(attrSpace) != 1) { 00963 Msg::print(Msg::SevWarning, "Bad attribute rank for attribute " 00964 + string(name)); 00965 if (name) { 00966 delete[] name; 00967 } 00968 continue; 00969 } 00970 00971 hsize_t dims[1]; 00972 H5Sget_simple_extent_dims(attrSpace, dims, NULL); 00973 00974 if (typeClass == H5T_INTEGER) { 00975 if (dims[0] == 1){ 00976 int value; 00977 if (!readAttribute(metadata_id, name, dims[0], value)) 00978 Msg::print(Msg::SevWarning, "Failed to read metadata " 00979 + string(name)); 00980 metadata().setIntMetadata(name, value); 00981 } 00982 else if (dims[0] == 3){ 00983 V3i value; 00984 if (!readAttribute(metadata_id, name, dims[0], value.x)) 00985 Msg::print(Msg::SevWarning, "Failed to read metadata " + 00986 string(name) ); 00987 metadata().setVecIntMetadata(name, value); 00988 } 00989 else { 00990 Msg::print(Msg::SevWarning, 00991 "Attribute of size " + 00992 boost::lexical_cast<std::string>(dims[0]) 00993 + " is not valid for metadata"); 00994 } 00995 } 00996 else if (typeClass == H5T_FLOAT) { 00997 if (dims[0] == 1){ 00998 float value; 00999 if (!readAttribute(metadata_id, name, dims[0], value)) 01000 Msg::print(Msg::SevWarning, "Failed to read metadata " + 01001 string(name) ); 01002 01003 metadata().setFloatMetadata(name, value); 01004 } 01005 else if (dims[0] == 3){ 01006 V3f value; 01007 if (!readAttribute(metadata_id, name, dims[0], value.x)) 01008 Msg::print(Msg::SevWarning, "Failed to read metadata "+ 01009 string(name) ); 01010 metadata().setVecFloatMetadata(name, value); 01011 } 01012 else { 01013 Msg::print(Msg::SevWarning, "Attribute of size " + 01014 boost::lexical_cast<std::string>(dims[0]) + 01015 " is not valid for metadata"); 01016 } 01017 } 01018 else { 01019 Msg::print(Msg::SevWarning, "Attribute '" + string(name) + 01020 + "' has unsupported data type for metadata"); 01021 01022 } 01023 } 01024 } 01025 if (name) { 01026 delete[] name; 01027 } 01028 } 01029 } 01030 } 01031 01032 return true; 01033 } 01034 01035 //----------------------------------------------------------------------------// 01036 01037 bool 01038 Field3DInputFile:: 01039 readGroupMembership(GroupMembershipMap &gpMembershipMap) 01040 { 01041 if (!H5Lexists(m_file, "field3d_group_membership", H5P_DEFAULT)) { 01042 return false; 01043 } 01044 01045 H5ScopedGopen memberGroup(m_file, "field3d_group_membership"); 01046 if (memberGroup < 0) { 01047 return false; 01048 } 01049 01050 typedef boost::tokenizer<boost::char_separator<char> > Tok; 01051 01052 hsize_t num_attrs = H5Aget_num_attrs(memberGroup); 01053 if (num_attrs > 0) { 01054 01055 for (hsize_t idx=0; idx < num_attrs ; ++idx) { 01056 H5ScopedAopenIdx attrIdx(memberGroup, idx); 01057 size_t len = H5Aget_name(attrIdx.id(), 0, NULL); 01058 if (len>0) { 01059 char *name = new char[len+1]; 01060 if (H5Aget_name(attrIdx.id(), len+1, name) > 0) { 01061 01062 if (string(name) == "is_field3d_group_membership") 01063 continue; 01064 01065 H5ScopedAopen attr(memberGroup, name, H5P_DEFAULT); 01066 H5ScopedAget_space attrSpace(attr); 01067 H5ScopedAget_type attrType(attr); 01068 H5T_class_t typeClass = H5Tget_class(attrType); 01069 01070 if (typeClass == H5T_STRING) { 01071 string value; 01072 if (!readAttribute(memberGroup, name, value)) { 01073 Msg::print(Msg::SevWarning, 01074 "Failed to read group membership data " 01075 + string(name)); 01076 continue; 01077 } 01078 01079 { 01080 boost::char_separator<char> sep(" :"); 01081 Tok tok(value, sep); 01082 string new_value; 01083 for(Tok::iterator beg=tok.begin(); beg!=tok.end();){ 01084 01085 string fieldgroup = *beg; ++beg; 01086 fieldgroup = removeUniqueId(fieldgroup) + ":" + *beg; ++beg; 01087 new_value += fieldgroup + " "; 01088 } 01089 01090 m_groupMembership[name] = value; 01091 gpMembershipMap[name] = new_value; 01092 } 01093 } 01094 } 01095 } 01096 } 01097 } 01098 01099 return true; 01100 } 01101 01102 //----------------------------------------------------------------------------// 01103 // Field3DFile-related callback functions 01104 //----------------------------------------------------------------------------// 01105 01106 namespace InputFile { 01107 01108 //----------------------------------------------------------------------------// 01109 01110 herr_t parsePartitions(hid_t loc_id, const char *itemName, 01111 const H5L_info_t *linfo, void *opdata) 01112 { 01113 herr_t status; 01114 H5O_info_t infobuf; 01115 01116 status = H5Oget_info_by_name(loc_id, itemName, &infobuf, H5P_DEFAULT); 01117 01118 if (status < 0) { 01119 return -1; 01120 } 01121 01122 if (infobuf.type == H5O_TYPE_GROUP) { 01123 01124 // Check that we have a name 01125 if (!itemName) { 01126 return -1; 01127 } 01128 01129 // check that this group is not "groupMembership" 01130 if (string(itemName) != "field3d_group_membership" && 01131 string(itemName) != "field3d_global_metadata") 01132 { 01133 01134 // Get a pointer to the file data structure 01135 Field3DInputFile* fileObject = static_cast<Field3DInputFile*>(opdata); 01136 if (!fileObject) { 01137 return -1; 01138 } 01139 01140 return fileObject->parsePartition(loc_id, itemName); 01141 } 01142 } 01143 return 0; 01144 } 01145 01146 //----------------------------------------------------------------------------// 01147 01148 herr_t parseLayers(hid_t loc_id, const char *itemName, 01149 const H5L_info_t *linfo, void *opdata) 01150 { 01151 herr_t status; 01152 H5O_info_t infobuf; 01153 01154 status = H5Oget_info_by_name (loc_id, itemName, &infobuf, H5P_DEFAULT); 01155 01156 if (infobuf.type == H5O_TYPE_GROUP) { 01157 01158 // Check that we have a name 01159 if (!itemName) 01160 return -1; 01161 01162 // Get a pointer to the file data structure 01163 ParseLayersInfo* info = static_cast<ParseLayersInfo*>(opdata); 01164 if (!info) 01165 return -1; 01166 01167 // Open up the layer group 01168 H5ScopedGopen layerGroup(loc_id, itemName); 01169 01170 // Check if it's a layer 01171 string classType; 01172 try { 01173 if (!readAttribute(layerGroup.id(), "class_type", classType)) { 01174 return 0; 01175 } 01176 if (classType == string("field3d_layer")) 01177 return info->file->parseLayer(layerGroup.id(), info->partitionName, 01178 itemName); 01179 01180 } 01181 catch (MissingAttributeException &e) { 01182 01183 } 01184 return 0; 01185 01186 } 01187 01188 return 0; 01189 } 01190 01191 //----------------------------------------------------------------------------// 01192 01193 } // namespace InputFile 01194 01195 //----------------------------------------------------------------------------// 01196 // Field3DOutputFile implementations 01197 //----------------------------------------------------------------------------// 01198 01199 Field3DOutputFile::Field3DOutputFile() 01200 { 01201 // Empty 01202 } 01203 01204 //----------------------------------------------------------------------------// 01205 01206 Field3DOutputFile::~Field3DOutputFile() 01207 { 01208 01209 } 01210 01211 //----------------------------------------------------------------------------// 01212 01215 bool Field3DOutputFile::create(const string &filename, CreateMode cm) 01216 { 01217 closeInternal(); 01218 01219 bool success = true; 01220 01221 try { 01222 01223 hid_t faid = H5Pcreate(H5P_FILE_ACCESS); 01224 H5Pset_libver_bounds(faid, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST); 01225 01226 // Create new file 01227 switch (cm) { 01228 case OverwriteMode: 01229 m_file = H5Fcreate(filename.c_str(), 01230 H5F_ACC_TRUNC, H5P_DEFAULT, faid); 01231 break; 01232 case FailOnExisting: 01233 m_file = H5Fcreate(filename.c_str(), 01234 H5F_ACC_EXCL, H5P_DEFAULT, faid); 01235 break; 01236 } 01237 01238 // Check that file was created 01239 if (m_file < 0) 01240 throw ErrorCreatingFileException(filename); 01241 01242 // Create a version attribute on the root node 01243 if (!writeAttribute(m_file, k_versionAttrName, 3, 01244 k_currentFileVersion[0])) { 01245 Msg::print(Msg::SevWarning, "Adding version number."); 01246 closeInternal(); 01247 return false; 01248 } 01249 01250 } 01251 catch (ErrorCreatingFileException &e) { 01252 Msg::print(Msg::SevWarning, "Couldn't create file: " + string(e.what()) ); 01253 success = false; 01254 } 01255 catch (WriteAttributeException &e) { 01256 Msg::print(Msg::SevWarning, "In file : " + filename + 01257 " - Couldn't add attribute " + string(e.what()) ); 01258 success = false; 01259 } 01260 catch (...) { 01261 Msg::print(Msg::SevWarning, 01262 "Unknown error when creating file: " + filename ); 01263 success = false; 01264 } 01265 01266 return success; 01267 } 01268 01269 //----------------------------------------------------------------------------// 01270 01271 bool Field3DOutputFile::writeMapping(hid_t partitionGroup, 01272 FieldMapping::Ptr mapping) 01273 { 01274 try { 01275 // Make a group under the partition to store the mapping data 01276 H5ScopedGcreate mappingGroup(partitionGroup, k_mappingStr); 01277 if (mappingGroup.id() < 0) 01278 throw CreateGroupException(k_mappingStr); 01279 // Let FieldMappingIO handle the rest 01280 if (!writeFieldMapping(mappingGroup.id(), mapping)) 01281 throw WriteMappingException(k_mappingStr); 01282 } 01283 catch (CreateGroupException &e) { 01284 Msg::print(Msg::SevWarning, "Couldn't create group: " + string(e.what()) ); 01285 throw WriteMappingException(k_mappingStr); 01286 } 01287 return true; 01288 } 01289 01290 //----------------------------------------------------------------------------// 01291 01292 bool Field3DOutputFile::writeMetadata(hid_t metadataGroup, FieldBase::Ptr field) 01293 { 01294 using namespace Hdf5Util; 01295 01296 { 01297 FieldMetadata<FieldBase>::StrMetadata::const_iterator i = 01298 field->metadata().strMetadata().begin(); 01299 FieldMetadata<FieldBase>::StrMetadata::const_iterator end = 01300 field->metadata().strMetadata().end(); 01301 for (; i != end; ++i) { 01302 if (!writeAttribute(metadataGroup, i->first, i->second)) 01303 { 01304 Msg::print(Msg::SevWarning, "Writing attribute " + i->first ); 01305 return false; 01306 } 01307 } 01308 } 01309 01310 { 01311 FieldMetadata<FieldBase>::IntMetadata::const_iterator i = 01312 field->metadata().intMetadata().begin(); 01313 FieldMetadata<FieldBase>::IntMetadata::const_iterator end = 01314 field->metadata().intMetadata().end(); 01315 for (; i != end; ++i) { 01316 if (!writeAttribute(metadataGroup, i->first, 1, i->second)) 01317 { 01318 Msg::print(Msg::SevWarning, "Writing attribute " + i->first); 01319 return false; 01320 } 01321 } 01322 } 01323 01324 { 01325 FieldMetadata<FieldBase>::FloatMetadata::const_iterator i = 01326 field->metadata().floatMetadata().begin(); 01327 FieldMetadata<FieldBase>::FloatMetadata::const_iterator end = 01328 field->metadata().floatMetadata().end(); 01329 for (; i != end; ++i) { 01330 if (!writeAttribute(metadataGroup, i->first, 1, i->second)) 01331 { 01332 Msg::print(Msg::SevWarning, "Writing attribute " + i->first); 01333 return false; 01334 } 01335 } 01336 } 01337 01338 { 01339 FieldMetadata<FieldBase>::VecIntMetadata::const_iterator i = 01340 field->metadata().vecIntMetadata().begin(); 01341 FieldMetadata<FieldBase>::VecIntMetadata::const_iterator end = 01342 field->metadata().vecIntMetadata().end(); 01343 for (; i != end; ++i) { 01344 if (!writeAttribute(metadataGroup, i->first, 3, i->second.x)) 01345 { 01346 Msg::print(Msg::SevWarning, "Writing attribute " + i->first); 01347 return false; 01348 } 01349 } 01350 } 01351 01352 { 01353 FieldMetadata<FieldBase>::VecFloatMetadata::const_iterator i = 01354 field->metadata().vecFloatMetadata().begin(); 01355 FieldMetadata<FieldBase>::VecFloatMetadata::const_iterator end = 01356 field->metadata().vecFloatMetadata().end(); 01357 for (; i != end; ++i) { 01358 if (!writeAttribute(metadataGroup, i->first, 3, i->second.x)) 01359 { 01360 Msg::print(Msg::SevWarning, "Writing attribute " + i->first); 01361 return false; 01362 } 01363 } 01364 01365 } 01366 01367 return true; 01368 01369 } 01370 01371 //----------------------------------------------------------------------------// 01372 01373 bool Field3DOutputFile::writeMetadata(hid_t metadataGroup) 01374 { 01375 using namespace Hdf5Util; 01376 01377 { 01378 FieldMetadata<Field3DFileBase>::StrMetadata::const_iterator i = 01379 metadata().strMetadata().begin(); 01380 FieldMetadata<Field3DFileBase>::StrMetadata::const_iterator end = 01381 metadata().strMetadata().end(); 01382 for (; i != end; ++i) { 01383 if (!writeAttribute(metadataGroup, i->first, i->second)) 01384 { 01385 Msg::print(Msg::SevWarning, "Writing attribute " + i->first ); 01386 return false; 01387 } 01388 } 01389 } 01390 01391 { 01392 FieldMetadata<Field3DFileBase>::IntMetadata::const_iterator i = 01393 metadata().intMetadata().begin(); 01394 FieldMetadata<Field3DFileBase>::IntMetadata::const_iterator end = 01395 metadata().intMetadata().end(); 01396 for (; i != end; ++i) { 01397 if (!writeAttribute(metadataGroup, i->first, 1, i->second)) 01398 { 01399 Msg::print(Msg::SevWarning, "Writing attribute " + i->first); 01400 return false; 01401 } 01402 } 01403 } 01404 01405 { 01406 FieldMetadata<Field3DFileBase>::FloatMetadata::const_iterator i = 01407 metadata().floatMetadata().begin(); 01408 FieldMetadata<Field3DFileBase>::FloatMetadata::const_iterator end = 01409 metadata().floatMetadata().end(); 01410 for (; i != end; ++i) { 01411 if (!writeAttribute(metadataGroup, i->first, 1, i->second)) 01412 { 01413 Msg::print(Msg::SevWarning, "Writing attribute " + i->first); 01414 return false; 01415 } 01416 } 01417 } 01418 01419 { 01420 FieldMetadata<Field3DFileBase>::VecIntMetadata::const_iterator i = 01421 metadata().vecIntMetadata().begin(); 01422 FieldMetadata<Field3DFileBase>::VecIntMetadata::const_iterator end = 01423 metadata().vecIntMetadata().end(); 01424 for (; i != end; ++i) { 01425 if (!writeAttribute(metadataGroup, i->first, 3, i->second.x)) 01426 { 01427 Msg::print(Msg::SevWarning, "Writing attribute " + i->first); 01428 return false; 01429 } 01430 } 01431 } 01432 01433 { 01434 FieldMetadata<Field3DFileBase>::VecFloatMetadata::const_iterator i = 01435 metadata().vecFloatMetadata().begin(); 01436 FieldMetadata<Field3DFileBase>::VecFloatMetadata::const_iterator end = 01437 metadata().vecFloatMetadata().end(); 01438 for (; i != end; ++i) { 01439 if (!writeAttribute(metadataGroup, i->first, 3, i->second.x)) 01440 { 01441 Msg::print(Msg::SevWarning, "Writing attribute " + i->first); 01442 return false; 01443 } 01444 } 01445 01446 } 01447 01448 return true; 01449 01450 } 01451 01452 //----------------------------------------------------------------------------// 01453 01454 bool 01455 Field3DOutputFile::writeGlobalMetadata() 01456 { 01457 01458 // Add metadata group and write it out 01459 H5ScopedGcreate metadataGroup(m_file, "field3d_global_metadata"); 01460 if (metadataGroup.id() < 0) { 01461 Msg::print(Msg::SevWarning, "Error creating group: file metadata"); 01462 return false; 01463 } 01464 if (!writeMetadata(metadataGroup.id())) { 01465 Msg::print(Msg::SevWarning, "Error writing file metadata."); 01466 return false; 01467 } 01468 01469 return true; 01470 } 01471 01472 //----------------------------------------------------------------------------// 01473 01474 bool 01475 Field3DOutputFile::writeGroupMembership() 01476 { 01477 using namespace std; 01478 using namespace Hdf5Util; 01479 01480 if (!m_groupMembership.size()) 01481 return true; 01482 01483 H5ScopedGcreate group(m_file, "field3d_group_membership"); 01484 if (group < 0) { 01485 Msg::print(Msg::SevWarning, 01486 "Error creating field3d_group_membership group."); 01487 return false; 01488 } 01489 01490 if (!writeAttribute(group, "is_field3d_group_membership", "1")) { 01491 Msg::print(Msg::SevWarning, 01492 "Failed to write field3d_group_membership attribute."); 01493 return false; 01494 } 01495 01496 std::map<std::string, std::string>::const_iterator iter = 01497 m_groupMembership.begin(); 01498 std::map<std::string, std::string>::const_iterator iEnd = 01499 m_groupMembership.end(); 01500 01501 for (; iter != iEnd; ++iter) { 01502 if (!writeAttribute(group, iter->first, iter->second)) { 01503 Msg::print(Msg::SevWarning, 01504 "Failed to write groupMembership string: "+ iter->first); 01505 return false; 01506 } 01507 } 01508 01509 return true; 01510 } 01511 01512 //----------------------------------------------------------------------------// 01513 01514 std::string 01515 Field3DOutputFile::incrementPartitionName(std::string &partitionName) 01516 { 01517 std::string myPartitionName = removeUniqueId(partitionName); 01518 int nextIdx = -1; 01519 if (m_partitionCount.find(myPartitionName) != m_partitionCount.end()) { 01520 nextIdx = ++m_partitionCount[myPartitionName]; 01521 } else { 01522 nextIdx = 0; 01523 m_partitionCount[myPartitionName] = 0; 01524 } 01525 01526 return makeIntPartitionName(myPartitionName, nextIdx); 01527 } 01528 01529 //----------------------------------------------------------------------------// 01530 // Debug 01531 //----------------------------------------------------------------------------// 01532 01533 void Field3DFileBase::printHierarchy() const 01534 { 01535 // For each partition 01536 for (PartitionList::const_iterator i = m_partitions.begin(); 01537 i != m_partitions.end(); ++i) { 01538 cout << "Name: " << (**i).name << endl; 01539 if ((**i).mapping) 01540 cout << " Mapping: " << (**i).mapping->className() << endl; 01541 else 01542 cout << " Mapping: NULL" << endl; 01543 cout << " Scalar layers: " << endl; 01544 vector<string> sNames; 01545 (**i).getScalarLayerNames(sNames); 01546 for_each(sNames.begin(), sNames.end(), print<string>(4)); 01547 cout << " Vector layers: " << endl; 01548 vector<string> vNames; 01549 (**i).getVectorLayerNames(vNames); 01550 for_each(vNames.begin(), vNames.end(), print<string>(4)); 01551 } 01552 } 01553 01554 //----------------------------------------------------------------------------// 01555 // Function Implementations 01556 //----------------------------------------------------------------------------// 01557 01558 bool writeField(hid_t layerGroup, FieldBase::Ptr field) 01559 { 01560 ClassFactory &factory = ClassFactory::singleton(); 01561 01562 FieldIO::Ptr io = factory.createFieldIO(field->className()); 01563 assert(io != 0); 01564 if (!io) { 01565 Msg::print(Msg::SevWarning, "Unable to find class type: " + 01566 field->className()); 01567 return false; 01568 } 01569 01570 // Add class name attribute 01571 if (!writeAttribute(layerGroup, k_classNameAttrName, 01572 field->className())) { 01573 Msg::print(Msg::SevWarning, "Error adding class name attribute."); 01574 return false; 01575 } 01576 01577 return io->write(layerGroup, field); 01578 } 01579 01580 //----------------------------------------------------------------------------// 01581 01582 FieldMapping::Ptr readFieldMapping(hid_t mappingGroup) 01583 { 01584 ClassFactory &factory = ClassFactory::singleton(); 01585 01586 std::string className; 01587 01588 if (!readAttribute(mappingGroup, k_mappingTypeAttrName, className)) { 01589 Msg::print(Msg::SevWarning, "Couldn't find " + k_mappingTypeAttrName + 01590 " attribute"); 01591 return FieldMapping::Ptr(); 01592 } 01593 01594 FieldMappingIO::Ptr io = factory.createFieldMappingIO(className); 01595 assert(io != 0); 01596 if (!io) { 01597 Msg::print(Msg::SevWarning, "Unable to find class type: " + 01598 className); 01599 return FieldMapping::Ptr(); 01600 } 01601 01602 01603 FieldMapping::Ptr mapping = io->read(mappingGroup); 01604 if (!mapping) { 01605 Msg::print(Msg::SevWarning, "Couldn't read mapping"); 01606 return FieldMapping::Ptr(); 01607 } 01608 01609 return mapping; 01610 } 01611 01612 //----------------------------------------------------------------------------// 01613 01614 bool writeFieldMapping(hid_t mappingGroup, FieldMapping::Ptr mapping) 01615 { 01616 ClassFactory &factory = ClassFactory::singleton(); 01617 01618 std::string className = mapping->className(); 01619 01620 if (!writeAttribute(mappingGroup, k_mappingTypeAttrName, className)) { 01621 Msg::print(Msg::SevWarning, "Couldn't add " + className + " attribute"); 01622 return false; 01623 } 01624 01625 FieldMappingIO::Ptr io = factory.createFieldMappingIO(className); 01626 assert(io != 0); 01627 if (!io) { 01628 Msg::print(Msg::SevWarning, "Unable to find class type: " + 01629 className); 01630 return false; 01631 } 01632 01633 return io->write(mappingGroup, mapping); 01634 } 01635 01636 //----------------------------------------------------------------------------// 01637 01638 FIELD3D_NAMESPACE_SOURCE_CLOSE 01639 01640 //----------------------------------------------------------------------------//