From 71f4d53b7398f11cb98eb4fe20e484003aa058b8 Mon Sep 17 00:00:00 2001 From: Ross Whitfield Date: Thu, 16 Jan 2025 14:36:53 +1100 Subject: [PATCH 1/9] Update LoadMDTest and LoadNexusProcessedTest --- .../test/LoadNexusProcessedTest.h | 23 ++++++++----------- Framework/MDAlgorithms/test/LoadMDTest.h | 23 ++++++------------- 2 files changed, 16 insertions(+), 30 deletions(-) diff --git a/Framework/DataHandling/test/LoadNexusProcessedTest.h b/Framework/DataHandling/test/LoadNexusProcessedTest.h index bf192583b898..a6cb5421bcf4 100644 --- a/Framework/DataHandling/test/LoadNexusProcessedTest.h +++ b/Framework/DataHandling/test/LoadNexusProcessedTest.h @@ -27,13 +27,14 @@ #include "MantidGeometry/Instrument.h" #include "MantidGeometry/Instrument/InstrumentDefinitionParser.h" #include "MantidHistogramData/Histogram.h" +#include "MantidNexus/H5Util.h" + +#include #include "SaveNexusProcessedTest.h" #include -#include - #include #include @@ -45,8 +46,11 @@ using namespace Mantid::Kernel; using namespace Mantid::DataObjects; using namespace Mantid::API; using namespace Mantid::HistogramData; +using namespace Mantid::NeXus; using Mantid::detid_t; +using namespace H5; + // Note that this suite tests an old version of Nexus processed files that we // continue to support. // LoadRawSaveNxsLoadNxs tests the current version of Nexus processed by loading @@ -797,18 +801,9 @@ class LoadNexusProcessedTest : public CxxTest::TestSuite { // Remove the coordinate_system entry so it falls back on the log. NeXus // can't do this so use the HDF5 API directly - auto fid = H5Fopen(filePath.c_str(), H5F_ACC_RDWR, H5P_DEFAULT); - auto mantid_id = H5Gopen(fid, "mantid_workspace_1", H5P_DEFAULT); - auto peaks_id = H5Gopen(mantid_id, "peaks_workspace", H5P_DEFAULT); - if (peaks_id > 0) { - H5Ldelete(peaks_id, "coordinate_system", H5P_DEFAULT); - H5Gclose(peaks_id); - H5Gclose(mantid_id); - } else { - TS_FAIL("Cannot unlink coordinate_system group. Test file has unexpected " - "structure."); - } - H5Fclose(fid); + H5File h5file(filePath.c_str(), H5F_ACC_RDWR); + H5Util::deleteObjectLink(h5file, "/mantid_workspace_1/peaks_workspace/coordinate_system"); + h5file.close(); LoadNexusProcessed loadAlg; loadAlg.setChild(true); diff --git a/Framework/MDAlgorithms/test/LoadMDTest.h b/Framework/MDAlgorithms/test/LoadMDTest.h index 378238cc32f3..e65f6f2c48eb 100644 --- a/Framework/MDAlgorithms/test/LoadMDTest.h +++ b/Framework/MDAlgorithms/test/LoadMDTest.h @@ -23,16 +23,18 @@ #include "MantidGeometry/MDGeometry/QSample.h" #include "MantidKernel/Strings.h" #include "MantidMDAlgorithms/LoadMD.h" +#include "MantidNexus/H5Util.h" +#include #include -#include - using namespace Mantid; using namespace Mantid::DataObjects; using namespace Mantid::MDAlgorithms; using namespace Mantid::API; using namespace Mantid::Kernel; +using namespace Mantid::NeXus; +using namespace H5; class LoadMDTest : public CxxTest::TestSuite { public: @@ -618,7 +620,7 @@ class LoadMDTest : public CxxTest::TestSuite { } Mantid::API::IMDWorkspace_sptr testSaveAndLoadWorkspace(const Mantid::API::IMDWorkspace_sptr &inputWS, - const char *rootGroup, const bool rmCoordField = false) { + std::string rootGroup, const bool rmCoordField = false) { const std::string fileName = "SaveMDSpecialCoordinatesTest.nxs"; SaveMD2 saveAlg; saveAlg.setChild(true); @@ -630,19 +632,8 @@ class LoadMDTest : public CxxTest::TestSuite { std::string this_fileName = saveAlg.getProperty("Filename"); if (rmCoordField) { - // Remove the coordinate_system entry so it falls back on the log. NeXus - // can't do this - // so use the HDF5 API directly - auto fid = H5Fopen(this_fileName.c_str(), H5F_ACC_RDWR, H5P_DEFAULT); - auto gid = H5Gopen(fid, rootGroup, H5P_DEFAULT); - if (gid > 0) { - H5Ldelete(gid, "coordinate_system", H5P_DEFAULT); - H5Gclose(gid); - } else { - TS_FAIL("Cannot open MDEventWorkspace group. Test file has unexpected " - "structure."); - } - H5Fclose(fid); + H5File h5file(this_fileName.c_str(), H5F_ACC_RDWR); + H5Util::deleteObjectLink(h5file, rootGroup + "/coordinate_system"); } LoadMD loadAlg; From 28c5ef615c67ce8adbfe166c8addacf75b5602a0 Mon Sep 17 00:00:00 2001 From: Ross Whitfield Date: Fri, 17 Jan 2025 12:36:42 +1100 Subject: [PATCH 2/9] Update LoadSassena --- .../inc/MantidDataHandling/LoadSassena.h | 12 ++-- Framework/DataHandling/src/LoadSassena.cpp | 72 ++++++++----------- 2 files changed, 37 insertions(+), 47 deletions(-) diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSassena.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSassena.h index 1ddb6e162ef8..9e4015e8f99b 100644 --- a/Framework/DataHandling/inc/MantidDataHandling/LoadSassena.h +++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSassena.h @@ -15,7 +15,7 @@ #include "MantidDataObjects/Workspace2D.h" #include "MantidKernel/NexusDescriptor.h" -#include +#include namespace Mantid { @@ -62,17 +62,17 @@ class MANTID_DATAHANDLING_DLL LoadSassena : public API::IFileLoader &buf); + void dataSetDouble(const H5::H5File &h5file, const std::string &setName, std::vector &buf); /// Load qvectors dataset, calculate modulus of vectors - HistogramData::Points loadQvectors(const hid_t &h5file, const API::WorkspaceGroup_sptr &gws, + HistogramData::Points loadQvectors(const H5::H5File &h5file, const API::WorkspaceGroup_sptr &gws, std::vector &sorting_indexes); /// Load structure factor asa function of q-vector modulus - void loadFQ(const hid_t &h5file, const API::WorkspaceGroup_sptr &gws, const std::string &setName, + void loadFQ(const H5::H5File &h5file, const API::WorkspaceGroup_sptr &gws, const std::string &setName, const HistogramData::Points &qvmod, const std::vector &sorting_indexes); /// Load time-dependent structure factor - void loadFQT(const hid_t &h5file, const API::WorkspaceGroup_sptr &gws, const std::string &setName, + void loadFQT(const H5::H5File &h5file, const API::WorkspaceGroup_sptr &gws, const std::string &setName, const HistogramData::Points &qvmod, const std::vector &sorting_indexes); private: diff --git a/Framework/DataHandling/src/LoadSassena.cpp b/Framework/DataHandling/src/LoadSassena.cpp index 1616e5a976e7..23eb94d0705d 100644 --- a/Framework/DataHandling/src/LoadSassena.cpp +++ b/Framework/DataHandling/src/LoadSassena.cpp @@ -17,8 +17,7 @@ #include "MantidKernel/Exception.h" #include "MantidKernel/Unit.h" #include "MantidKernel/UnitFactory.h" - -#include +#include "MantidNexus/H5Util.h" #include @@ -61,14 +60,8 @@ void LoadSassena::registerWorkspace(const API::WorkspaceGroup_sptr &gws, const s * @param dims storing dimensionality */ -herr_t LoadSassena::dataSetInfo(const hid_t &h5file, const std::string &setName, hsize_t *dims) const { - H5T_class_t class_id; - size_t type_size; - herr_t errorcode = H5LTget_dataset_info(h5file, setName.c_str(), dims, &class_id, &type_size); - if (errorcode < 0) { - g_log.error("Unable to read " + setName + " dataset info"); - } - return errorcode; +void LoadSassena::dataSetInfo(const H5::H5File &h5file, const std::string &setName, hsize_t *dims) const { + h5file.openDataSet(setName).getSpace().getSimpleExtentDims(dims); } /** @@ -77,12 +70,8 @@ herr_t LoadSassena::dataSetInfo(const hid_t &h5file, const std::string &setName, * @param setName string name of dataset * @param buf storing dataset */ -herr_t LoadSassena::dataSetDouble(const hid_t &h5file, const std::string &setName, std::vector &buf) { - herr_t errorcode = H5LTread_dataset_double(h5file, setName.c_str(), buf.data()); - if (errorcode < 0) { - this->g_log.error("Cannot read " + setName + " dataset"); - } - return errorcode; +void LoadSassena::dataSetDouble(const H5::H5File &h5file, const std::string &setName, std::vector &buf) { + Mantid::NeXus::H5Util::readArray1DCoerce(h5file.openDataSet(setName), buf); } /* Helper object and function to sort modulus of Q-vectors @@ -100,7 +89,7 @@ bool compare(const mypair &left, const mypair &right) { return left.first < righ * @param sorting_indexes permutation of qvmod indexes to render it in * increasing order of momemtum transfer */ -HistogramData::Points LoadSassena::loadQvectors(const hid_t &h5file, const API::WorkspaceGroup_sptr &gws, +HistogramData::Points LoadSassena::loadQvectors(const H5::H5File &h5file, const API::WorkspaceGroup_sptr &gws, std::vector &sorting_indexes) { // store the modulus of the vector @@ -110,14 +99,18 @@ HistogramData::Points LoadSassena::loadQvectors(const hid_t &h5file, const API:: const std::string setName("qvectors"); hsize_t dims[3]; - if (dataSetInfo(h5file, setName, dims) < 0) { + try { + dataSetInfo(h5file, setName, dims); + } catch (H5::Exception &e) { throw Kernel::Exception::FileError("Unable to read " + setName + " dataset info:", m_filename); } + auto nq = static_cast(dims[0]); // number of q-vectors std::vector buf(nq * 3); - herr_t errorcode = this->dataSetDouble(h5file, "qvectors", buf); - if (errorcode < 0) { + try { + this->dataSetDouble(h5file, "qvectors", buf); + } catch (H5::Exception &e) { this->g_log.error("LoadSassena::loadQvectors cannot proceed"); qvmod.resize(0); return HistogramData::Points(std::move(qvmod)); @@ -169,13 +162,14 @@ HistogramData::Points LoadSassena::loadQvectors(const hid_t &h5file, const API:: * @param sorting_indexes permutation of qvmod indexes to render it in * increasing order of momemtum transfer */ -void LoadSassena::loadFQ(const hid_t &h5file, const API::WorkspaceGroup_sptr &gws, const std::string &setName, +void LoadSassena::loadFQ(const H5::H5File &h5file, const API::WorkspaceGroup_sptr &gws, const std::string &setName, const HistogramData::Points &qvmod, const std::vector &sorting_indexes) { auto nq = static_cast(qvmod.size()); // number of q-vectors std::vector buf(nq * 2); - herr_t errorcode = this->dataSetDouble(h5file, setName, buf); - if (errorcode < 0) { + try { + this->dataSetDouble(h5file, setName, buf); + } catch (H5::Exception &e) { this->g_log.error("LoadSassena::loadFQ cannot proceed"); return; } @@ -217,11 +211,13 @@ void LoadSassena::loadFQ(const hid_t &h5file, const API::WorkspaceGroup_sptr &gw * @param sorting_indexes permutation of qvmod indexes to render it in * increasing order of momemtum transfer */ -void LoadSassena::loadFQT(const hid_t &h5file, const API::WorkspaceGroup_sptr &gws, const std::string &setName, +void LoadSassena::loadFQT(const H5::H5File &h5file, const API::WorkspaceGroup_sptr &gws, const std::string &setName, const HistogramData::Points &qvmod, const std::vector &sorting_indexes) { hsize_t dims[3]; - if (dataSetInfo(h5file, setName, dims) < 0) { + try { + dataSetInfo(h5file, setName, dims); + } catch (H5::Exception &) { this->g_log.error("Unable to read " + setName + " dataset info"); this->g_log.error("LoadSassena::loadFQT cannot proceed"); return; @@ -231,8 +227,9 @@ void LoadSassena::loadFQT(const hid_t &h5file, const API::WorkspaceGroup_sptr &g auto nq = static_cast(qvmod.size()); // number of q-vectors std::vector buf(nq * nnt * 2); - herr_t errorcode = this->dataSetDouble(h5file, setName, buf); - if (errorcode < 0) { + try { + this->dataSetDouble(h5file, setName, buf); + } catch (H5::Exception &e) { this->g_log.error("LoadSassena::loadFQT cannot proceed"); return; } @@ -356,34 +353,27 @@ void LoadSassena::exec() { // open the HDF5 file for reading m_filename = this->getPropertyValue("Filename"); - hid_t h5file = H5Fopen(m_filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT); - if (h5file < 0) { + H5::H5File h5file; + try { + h5file = H5::H5File(m_filename.c_str(), H5F_ACC_RDONLY); + } catch (H5::FileIException &e) { this->g_log.error("Cannot open " + m_filename); throw Kernel::Exception::FileError("Unable to open:", m_filename); } - // find out the sassena version used - char cversion[16]; - if (H5LTget_attribute_string(h5file, "/", "sassena_version", cversion) < 0) { - this->g_log.error("Unable to read Sassena version"); - } - // const std::string version(cversion); - // determine which loader protocol to use based on the version - // to be done at a later time, maybe implement a Version class - // Block to read the Q-vectors std::vector sorting_indexes; const auto qvmod = this->loadQvectors(h5file, gws, sorting_indexes); if (qvmod.empty()) { this->g_log.error("No Q-vectors read. Unable to proceed"); - H5Fclose(h5file); + h5file.close(); return; } // iterate over the valid sets for (std::vector::const_iterator it = this->m_validSets.begin(); it != this->m_validSets.end(); ++it) { std::string setName = *it; - if (H5Lexists(h5file, setName.c_str(), H5P_DEFAULT)) { + if (h5file.nameExists(setName)) { if (setName == "fq" || setName == "fq0" || setName == "fq2") this->loadFQ(h5file, gws, setName, qvmod, sorting_indexes); else if (setName == "fqt") @@ -392,7 +382,7 @@ void LoadSassena::exec() { this->g_log.information("Dataset " + setName + " not present in file"); } // end of iterate over the valid sets - H5Fclose(h5file); + h5file.close(); } // end of LoadSassena::exec() } // namespace Mantid::DataHandling From 6b978985bae065857be8069a818ff97b5d889f7e Mon Sep 17 00:00:00 2001 From: Ross Whitfield Date: Fri, 17 Jan 2025 13:30:26 +1100 Subject: [PATCH 3/9] Update SaveNXSPETest --- Framework/DataHandling/src/LoadNXcanSAS.cpp | 8 ---- Framework/DataHandling/test/SaveNXSPETest.h | 44 ++++++++----------- Framework/Kernel/CMakeLists.txt | 1 - Framework/NexusCpp/CMakeLists.txt | 2 +- buildconfig/CMake/CommonSetup.cmake | 3 +- .../CMake/MantidFrameworkConfig.cmake.in | 2 +- 6 files changed, 22 insertions(+), 38 deletions(-) diff --git a/Framework/DataHandling/src/LoadNXcanSAS.cpp b/Framework/DataHandling/src/LoadNXcanSAS.cpp index f21e21a347d8..8ec00e4e40d1 100644 --- a/Framework/DataHandling/src/LoadNXcanSAS.cpp +++ b/Framework/DataHandling/src/LoadNXcanSAS.cpp @@ -483,15 +483,7 @@ void loadTransmissionData(H5::Group &transmission, const Mantid::API::MatrixWork else if (lambda.size() == workspace->blocksize() + 1) workspace->setBinEdges(0, std::move(lambda)); else { -#if defined(H5_USE_18_API) const std::string objectName{transmission.getObjName()}; -#else - const size_t nchars = H5Iget_name(transmission.getId(), nullptr, 0); - std::string objectName; - objectName.resize(nchars); - H5Iget_name(transmission.getId(), objectName.data(), - nchars + 1); // +1 for null terminator -#endif throw std::runtime_error("Unexpected array size for lambda in transmission group '" + objectName + "'. Expected length=" + std::to_string(workspace->blocksize()) + ", found length=" + std::to_string(lambda.size())); diff --git a/Framework/DataHandling/test/SaveNXSPETest.h b/Framework/DataHandling/test/SaveNXSPETest.h index 86d2ae55b09f..556f3c19481a 100644 --- a/Framework/DataHandling/test/SaveNXSPETest.h +++ b/Framework/DataHandling/test/SaveNXSPETest.h @@ -23,8 +23,8 @@ #include "boost/tuple/tuple.hpp" #include -#include -#include +#include "MantidNexus/H5Util.h" +#include #include @@ -261,53 +261,47 @@ class SaveNXSPETest : public CxxTest::TestSuite { std::vector()); } - auto h5file = H5Fopen(outputFile.c_str(), H5F_ACC_RDWR, H5P_DEFAULT); + H5::H5File h5file(outputFile, H5F_ACC_RDONLY); const char *dset = "/mantid_workspace/data/data"; int rank(0); - herr_t status = H5LTget_dataset_ndims(h5file, dset, &rank); - TS_ASSERT_EQUALS(0, status); + H5::DataSet dataset = h5file.openDataSet(dset); + rank = dataset.getSpace().getSimpleExtentNdims(); TS_ASSERT_EQUALS(2, rank); std::vector dims(rank); - H5T_class_t classId(H5T_NO_CLASS); - size_t typeSize(0); - status = H5LTget_dataset_info(h5file, dset, dims.data(), &classId, &typeSize); - TS_ASSERT_EQUALS(0, status); - TS_ASSERT_EQUALS(H5T_FLOAT, classId); - TS_ASSERT_EQUALS(8, typeSize); + dataset.getSpace().getSimpleExtentDims(dims.data()); + H5::DataType dataType = dataset.getDataType(); + TS_ASSERT_EQUALS(H5T_FLOAT, dataType.getClass()); + TS_ASSERT_EQUALS(8, dataType.getSize()); size_t bufferSize(dims[0] * dims[1]); std::vector signal(bufferSize), error(bufferSize); - status = H5LTread_dataset_double(h5file, dset, signal.data()); - TS_ASSERT_EQUALS(0, status); + Mantid::NeXus::H5Util::readArray1DCoerce(dataset, signal); const char *dsetErr = "/mantid_workspace/data/error"; - status = H5LTread_dataset_double(h5file, dsetErr, error.data()); - TS_ASSERT_EQUALS(0, status); + Mantid::NeXus::H5Util::readArray1DCoerce(h5file.openDataSet(dsetErr), error); //--------------------------------------------------------------- // check efixed const char *efixed_dset = "/mantid_workspace/NXSPE_info/fixed_energy"; - status = H5LTget_dataset_ndims(h5file, efixed_dset, &rank); - TS_ASSERT_EQUALS(0, status); + H5::DataSet efixed_dataset = h5file.openDataSet(efixed_dset); + rank = efixed_dataset.getSpace().getSimpleExtentNdims(); TS_ASSERT_EQUALS(1, rank); std::vector efix_dims(rank); - status = H5LTget_dataset_info(h5file, efixed_dset, efix_dims.data(), &classId, &typeSize); - TS_ASSERT_EQUALS(0, status); - TS_ASSERT_EQUALS(H5T_FLOAT, classId); - TS_ASSERT_EQUALS(8, typeSize); + efixed_dataset.getSpace().getSimpleExtentDims(efix_dims.data()); + H5::DataType efixed_dataType = efixed_dataset.getDataType(); + TS_ASSERT_EQUALS(H5T_FLOAT, efixed_dataType.getClass()); + TS_ASSERT_EQUALS(8, efixed_dataType.getSize()); size_t EnBuffer(efix_dims[0]); std::vector efixed(EnBuffer); - status = H5LTread_dataset_double(h5file, efixed_dset, efixed.data()); - TS_ASSERT_EQUALS(0, status); + Mantid::NeXus::H5Util::readArray1DCoerce(efixed_dataset, efixed); if (set_efixed) { TS_ASSERT_EQUALS(EnBuffer, 1); TS_ASSERT_DELTA(efixed[0], efix_value, 1.e-8); } - H5Fclose(h5file); - // Poco::File(outputFile).remove(); + h5file.close(); return boost::make_tuple(dims, signal, error, efixed); } diff --git a/Framework/Kernel/CMakeLists.txt b/Framework/Kernel/CMakeLists.txt index 804185f6682e..322b0a364ccd 100644 --- a/Framework/Kernel/CMakeLists.txt +++ b/Framework/Kernel/CMakeLists.txt @@ -498,7 +498,6 @@ target_link_libraries( GSL::gsl OpenSSL::SSL ${HDF5_LIBRARIES} - ${HDF5_HL_LIBRARIES} PRIVATE ${NETWORK_LIBRARIES} ) if(WIN32) diff --git a/Framework/NexusCpp/CMakeLists.txt b/Framework/NexusCpp/CMakeLists.txt index 482f352f7869..bbfab838b64e 100644 --- a/Framework/NexusCpp/CMakeLists.txt +++ b/Framework/NexusCpp/CMakeLists.txt @@ -39,7 +39,7 @@ set_target_properties( ) # H5_BUILT_AS_DYNAMIC_LIB required https://github.com/conda-forge/hdf5-feedstock/issues/58 target_compile_definitions(NexusCpp PUBLIC -DH5_BUILT_AS_DYNAMIC_LIB) -target_link_libraries(NexusCpp PUBLIC ${HDF4_DF_LIBRARY} ${HDF4_MFHDF_LIBRARY} ${HDF5_LIBRARIES} ${HDF5_HL_LIBRARIES}) +target_link_libraries(NexusCpp PUBLIC ${HDF4_DF_LIBRARY} ${HDF4_MFHDF_LIBRARY} ${HDF5_LIBRARIES}) if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set_target_properties(NexusCpp PROPERTIES INSTALL_RPATH "@loader_path/../MacOS;@loader_path/../Frameworks") diff --git a/buildconfig/CMake/CommonSetup.cmake b/buildconfig/CMake/CommonSetup.cmake index ab60b9217889..7da4bd194f81 100644 --- a/buildconfig/CMake/CommonSetup.cmake +++ b/buildconfig/CMake/CommonSetup.cmake @@ -102,11 +102,10 @@ if(BUILD_MANTIDFRAMEWORK) find_package( HDF5 MODULE - COMPONENTS C CXX HL + COMPONENTS C CXX REQUIRED ) set(HDF5_LIBRARIES hdf5::hdf5_cpp hdf5::hdf5) - set(HDF5_HL_LIBRARIES hdf5::hdf5_hl) endif() if(ENABLE_WORKBENCH) diff --git a/buildconfig/CMake/MantidFrameworkConfig.cmake.in b/buildconfig/CMake/MantidFrameworkConfig.cmake.in index b7598476b063..7dd324604e8f 100644 --- a/buildconfig/CMake/MantidFrameworkConfig.cmake.in +++ b/buildconfig/CMake/MantidFrameworkConfig.cmake.in @@ -12,7 +12,7 @@ find_dependency(GSL) find_dependency(HDF5) find_dependency(OpenSSL) find_dependency(OpenMP COMPONENTS CXX) -find_dependency(HDF5 COMPONENTS C CXX HL) +find_dependency(HDF5 COMPONENTS C CXX) find_dependency(Eigen3) set(_mypackage_module_path_save "${CMAKE_MODULE_PATH}") From c233036d19e8eb91520a642c773c49c1a3333331 Mon Sep 17 00:00:00 2001 From: Ross Whitfield Date: Fri, 17 Jan 2025 14:37:16 +1100 Subject: [PATCH 4/9] Remove H5ForwardCompatibility --- Framework/NexusGeometry/CMakeLists.txt | 2 - .../H5ForwardCompatibility.h | 31 --------- .../src/H5ForwardCompatibility.cpp | 64 ------------------- .../NexusGeometry/src/NexusGeometryParser.cpp | 24 ++++--- .../NexusGeometry/src/NexusGeometrySave.cpp | 35 +++++----- .../src/NexusGeometryUtilities.cpp | 3 +- .../NexusFileReader.h | 1 - 7 files changed, 29 insertions(+), 131 deletions(-) delete mode 100644 Framework/NexusGeometry/inc/MantidNexusGeometry/H5ForwardCompatibility.h delete mode 100644 Framework/NexusGeometry/src/H5ForwardCompatibility.cpp diff --git a/Framework/NexusGeometry/CMakeLists.txt b/Framework/NexusGeometry/CMakeLists.txt index fbae216c8e12..aad31f12cab5 100644 --- a/Framework/NexusGeometry/CMakeLists.txt +++ b/Framework/NexusGeometry/CMakeLists.txt @@ -1,5 +1,4 @@ set(SRC_FILES - src/H5ForwardCompatibility.cpp src/Hdf5Version.cpp src/InstrumentBuilder.cpp src/JSONGeometryParser.cpp @@ -14,7 +13,6 @@ set(SRC_FILES set(INC_FILES inc/MantidNexusGeometry/AbstractLogger.h - inc/MantidNexusGeometry/H5ForwardCompatibility.h inc/MantidNexusGeometry/Hdf5Version.h inc/MantidNexusGeometry/InstrumentBuilder.h inc/MantidNexusGeometry/JSONGeometryParser.h diff --git a/Framework/NexusGeometry/inc/MantidNexusGeometry/H5ForwardCompatibility.h b/Framework/NexusGeometry/inc/MantidNexusGeometry/H5ForwardCompatibility.h deleted file mode 100644 index a7e9602cc95e..000000000000 --- a/Framework/NexusGeometry/inc/MantidNexusGeometry/H5ForwardCompatibility.h +++ /dev/null @@ -1,31 +0,0 @@ -// Mantid Repository : https://github.com/mantidproject/mantid -// -// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI, -// NScD Oak Ridge National Laboratory, European Spallation Source, -// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS -// SPDX - License - Identifier: GPL - 3.0 + -#pragma once - -#include "MantidNexusGeometry/DllConfig.h" -#include -#include - -// Use forward compatibility for lower than 1.8.13 versions of HDF5 -#if ((H5_VERS_MAJOR > 1) || (H5_VERS_MAJOR >= 1 && H5_VERS_MINOR > 8) || \ - (H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >= 8 && H5_VERS_RELEASE > 12)) -#define H5_OBJ_NAME(obj) obj.getObjName() -#else -#define H5_OBJ_NAME(obj) Mantid::NexusGeometry::H5ForwardCompatibility::getObjName(obj) -#endif - -namespace Mantid { -namespace NexusGeometry { -namespace H5ForwardCompatibility { - -ssize_t getObjName(const H5::H5Object &obj, char *obj_name, size_t buf_size); -std::string getObjName(const H5::H5Object &obj); -std::string getObjName(const H5::H5File &obj); - -} // namespace H5ForwardCompatibility -} // namespace NexusGeometry -} // namespace Mantid diff --git a/Framework/NexusGeometry/src/H5ForwardCompatibility.cpp b/Framework/NexusGeometry/src/H5ForwardCompatibility.cpp deleted file mode 100644 index 5fcd50561d0c..000000000000 --- a/Framework/NexusGeometry/src/H5ForwardCompatibility.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// Mantid Repository : https://github.com/mantidproject/mantid -// -// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI, -// NScD Oak Ridge National Laboratory, European Spallation Source, -// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS -// SPDX - License - Identifier: GPL - 3.0 + -#include "MantidNexusGeometry/H5ForwardCompatibility.h" -#include //memset. -#include - -namespace Mantid::NexusGeometry::H5ForwardCompatibility { - -/* - * Function "getObjName" - * Ported from newer versions of the HDF API for forward compatibility to - * support HDF5 version < 1.8.13 - * https://portal.hdfgroup.org/display/HDF5/Software+Changes+from+Release+to+Release+for+HDF5-1.8 - */ -ssize_t getObjName(const H5::H5Object &obj, char *obj_name, size_t buf_size) { - // H5Iget_name will get buf_size-1 chars of the name to null terminate it - ssize_t name_size = H5Iget_name(obj.getId(), obj_name, buf_size); - - // If H5Iget_name returns a negative value, raise an exception - if (name_size < 0) { - throw H5::Exception("getObjName", "H5Iget_name failed"); - } else if (name_size == 0) { - throw H5::Exception("getObjName", "Object must have a name, but name length is 0"); - } - // Return length of the name - return (name_size); -} - -std::string getObjName(const H5::H5File &) { return "File Object"; } -std::string getObjName(const H5::H5Object &obj) { - std::string obj_name; // object name to return - - // Preliminary call to get the size of the object name - ssize_t name_size = H5Iget_name(obj.getId(), nullptr, static_cast(0)); - - // If H5Iget_name failed, throw exception - if (name_size < 0) { - throw H5::Exception("getObjName", "H5Iget_name failed"); - } else if (name_size == 0) { - throw H5::Exception("getObjName", "Object must have a name, but name length is 0"); - } - // Object's name exists, retrieve it - else { - char *name_C = new char[name_size + 1]; // temporary C-string - memset(name_C, 0, name_size + 1); // clear buffer - - // Use overloaded function - getObjName(obj, name_C, name_size + 1); - - // Convert the C object name to return - obj_name = name_C; - - // Clean up resource - delete[] name_C; - } - // Return object's name - return (obj_name); -} - -} // namespace Mantid::NexusGeometry::H5ForwardCompatibility diff --git a/Framework/NexusGeometry/src/NexusGeometryParser.cpp b/Framework/NexusGeometry/src/NexusGeometryParser.cpp index 24909b3ddd01..f7dc50b151f4 100644 --- a/Framework/NexusGeometry/src/NexusGeometryParser.cpp +++ b/Framework/NexusGeometry/src/NexusGeometryParser.cpp @@ -11,7 +11,6 @@ #include "MantidGeometry/Rendering/ShapeInfo.h" #include "MantidKernel/ChecksumHelper.h" #include "MantidNexusGeometry/AbstractLogger.h" -#include "MantidNexusGeometry/H5ForwardCompatibility.h" #include "MantidNexusGeometry/Hdf5Version.h" #include "MantidNexusGeometry/InstrumentBuilder.h" #include "MantidNexusGeometry/NexusGeometryDefinitions.h" @@ -56,22 +55,22 @@ template void validateStorageType(const DataSet &data) { if (H5T_FLOAT != typeClass) { throw std::runtime_error("Storage type mismatch. Expecting to extract a " "floating point number from " + - H5_OBJ_NAME(data)); + data.getObjName()); } if (sizeOfType != sizeof(ExpectedT)) { throw std::runtime_error("Storage type mismatch for floats. This operation " "is dangerous. Nexus stored has byte size:" + - std::to_string(sizeOfType) + " in " + H5_OBJ_NAME(data)); + std::to_string(sizeOfType) + " in " + data.getObjName()); } } else if (std::is_integral::value) { if (H5T_INTEGER != typeClass) { - throw std::runtime_error("Storage type mismatch. Expecting to extract a integer from " + H5_OBJ_NAME(data)); + throw std::runtime_error("Storage type mismatch. Expecting to extract a integer from " + data.getObjName()); } if (sizeOfType > sizeof(ExpectedT)) { // endianness not checked throw std::runtime_error("Storage type mismatch for integer. Result " "would result in truncation. Nexus stored has byte size:" + - std::to_string(sizeOfType) + " in " + H5_OBJ_NAME(data)); + std::to_string(sizeOfType) + " in " + data.getObjName()); } } } @@ -130,7 +129,7 @@ class Parser { ints = get1DDataset(object, dsName); } else { std::stringstream ss; - ss << "Cannot handle reading ints of size " << nxintsize << " from " << dsName << " in " << H5_OBJ_NAME(object) + ss << "Cannot handle reading ints of size " << nxintsize << " from " << dsName << " in " << object.getObjName() << ". Only 64 and 32 bit signed ints handled"; throw std::runtime_error(ss.str()); } @@ -149,7 +148,7 @@ class Parser { ints = convertVector(get1DDataset(object, dsName)); } else { std::stringstream ss; - ss << "Cannot handle reading ints of size " << nxintsize << " from " << dsName << " in " << H5_OBJ_NAME(object) + ss << "Cannot handle reading ints of size " << nxintsize << " from " << dsName << " in " << object.getObjName() << ". Only 64 and 32 bit signed ints handled"; throw std::runtime_error(ss.str()); } @@ -160,7 +159,7 @@ class Parser { typename std::enable_if::value, std::string>::type unsupportedNXFloatMessage(size_t nxfloatsize, const T &object, const std::string &dsName) { std::stringstream ss; - ss << "Cannot handle reading ints of size " << nxfloatsize << " from " << dsName << " in " << H5_OBJ_NAME(object) + ss << "Cannot handle reading ints of size " << nxfloatsize << " from " << dsName << " in " << object.getObjName() << ". Only 64 and 32 bit floats handled"; return ss.str(); } @@ -359,8 +358,7 @@ class Parser { Eigen::Transform getTransformations(const H5File &file, const Group &detectorGroup) { H5std_string dependency; // Get absolute dependency path - auto status = H5Gget_objinfo(detectorGroup.getId(), DEPENDS_ON.c_str(), false, nullptr); - if (status == 0) { + if (detectorGroup.nameExists(DEPENDS_ON)) { dependency = get1DStringDataset(DEPENDS_ON, detectorGroup); } else { return Eigen::Transform::Identity(); @@ -432,7 +430,7 @@ class Parser { transforms = rotation * transforms; } else { throw std::runtime_error("Unknown Transform type \"" + transformType + "\" found in " + - H5_OBJ_NAME(transformation) + " when parsing Nexus geometry"); + transformation.getObjName() + " when parsing Nexus geometry"); } } return transforms; @@ -645,7 +643,7 @@ class Parser { parseNexusCylinderDetector(shapeGroup, bankName, builder, detectorIds); } else { std::stringstream ss; - ss << "Shape group " << H5_OBJ_NAME(shapeGroup) << " has unknown geometry type specified via " << NX_CLASS; + ss << "Shape group " << shapeGroup.getObjName() << " has unknown geometry type specified via " << NX_CLASS; throw std::runtime_error(ss.str()); } } @@ -738,7 +736,7 @@ class Parser { for (auto &detectorGroup : detectorGroups) { // Transform in homogenous coordinates. Offsets will be rotated then bank // translation applied. - auto debug = H5_OBJ_NAME(detectorGroup); + auto debug = detectorGroup.getObjName(); Eigen::Transform transforms = getTransformations(file, detectorGroup); // Absolute bank position Eigen::Vector3d bankPos = transforms * Eigen::Vector3d{0, 0, 0}; diff --git a/Framework/NexusGeometry/src/NexusGeometrySave.cpp b/Framework/NexusGeometry/src/NexusGeometrySave.cpp index ea5cbc2798f4..e4a1e5f71c6a 100644 --- a/Framework/NexusGeometry/src/NexusGeometrySave.cpp +++ b/Framework/NexusGeometry/src/NexusGeometrySave.cpp @@ -22,7 +22,6 @@ #include "MantidIndexing/IndexInfo.h" #include "MantidKernel/EigenConversionHelpers.h" #include "MantidKernel/ProgressBase.h" -#include "MantidNexusGeometry/H5ForwardCompatibility.h" #include "MantidNexusGeometry/NexusGeometryDefinitions.h" #include "MantidNexusGeometry/NexusGeometryUtilities.h" #include @@ -64,7 +63,7 @@ struct SpectraMappings { * @return : new H5 Group object with name if did not throw. */ inline H5::Group tryCreateGroup(const H5::Group &parentGroup, const std::string &childGroupName) { - H5std_string parentGroupName = H5_OBJ_NAME(parentGroup); + H5std_string parentGroupName = parentGroup.getObjName(); for (hsize_t i = 0; i < parentGroup.getNumObjs(); ++i) { if (parentGroup.getObjTypeByIdx(i) == GROUP_TYPE) { H5std_string child = parentGroup.getObjnameByIdx(i); @@ -239,7 +238,7 @@ void writeXYZPixeloffset(H5::Group &grp, const Geometry::ComponentInfo &compInfo hsize_t dims[static_cast(1)]; dims[0] = nDetectorsInBank; - H5::DataSpace space = H5Screate_simple(rank, dims, nullptr); + H5::DataSpace space = H5::DataSpace(rank, dims, nullptr); if (!xIsZero) { xPixelOffset = grp.createDataSet(X_PIXEL_OFFSET, H5::PredType::NATIVE_DOUBLE, space); @@ -265,7 +264,7 @@ void write1DIntDataset(H5::Group &grp, const H5std_string &name, const std::vect const int rank = 1; hsize_t dims[1] = {static_cast(container.size())}; - H5::DataSpace space = H5Screate_simple(rank, dims, nullptr); + H5::DataSpace space = H5::DataSpace(rank, dims, nullptr); auto dataset = grp.createDataSet(name, H5::PredType::NATIVE_INT, space); if (!container.empty()) @@ -340,7 +339,7 @@ void writeNXMonitorNumber(H5::Group &grp, const int monitorID) { hsize_t dims[static_cast(1)]; dims[0] = static_cast(1); - H5::DataSpace space = H5Screate_simple(rank, dims, nullptr); + H5::DataSpace space = H5::DataSpace(rank, dims, nullptr); // these DataSets are duplicates of each other. written to the group to // handle the naming inconsistency. probably temporary. @@ -388,7 +387,7 @@ inline void writeLocation(H5::Group &grp, const Eigen::Vector3d &position) { auto unitVec = position.normalized(); // unit vector of the position vector std::vector stdNormPos = toStdVector(unitVec); // convert to std::vector - dspace = H5Screate_simple(drank, ddims, nullptr); // dataspace for dataset + dspace = H5::DataSpace(drank, ddims, nullptr); // dataspace for dataset location = grp.createDataSet(LOCATION, H5::PredType::NATIVE_DOUBLE, dspace); // dataset location location.write(&norm, H5::PredType::NATIVE_DOUBLE, @@ -398,7 +397,7 @@ inline void writeLocation(H5::Group &grp, const Eigen::Vector3d &position) { hsize_t adims[static_cast(3)]; // dimensions of attribute adims[0] = 3; // datapoints in attribute dimension 0 - aspace = H5Screate_simple(arank, adims, nullptr); // dataspace for attribute + aspace = H5::DataSpace(arank, adims, nullptr); // dataspace for attribute vector = location.createAttribute(VECTOR, H5::PredType::NATIVE_DOUBLE, aspace); // attribute vector vector.write(H5::PredType::NATIVE_DOUBLE, @@ -459,7 +458,7 @@ inline void writeOrientation(H5::Group &grp, const Eigen::Quaterniond &rotation, Eigen::Vector3d axisOfRotation = rotation.vec().normalized(); // angle axis std::vector stdNormAxis = toStdVector(axisOfRotation); // convert to std::vector - dspace = H5Screate_simple(drank, ddims, nullptr); // dataspace for dataset + dspace = H5::DataSpace(drank, ddims, nullptr); // dataspace for dataset orientation = grp.createDataSet(ORIENTATION, H5::PredType::NATIVE_DOUBLE, dspace); // dataset orientation orientation.write(&angle, H5::PredType::NATIVE_DOUBLE, @@ -469,7 +468,7 @@ inline void writeOrientation(H5::Group &grp, const Eigen::Quaterniond &rotation, hsize_t adims[static_cast(3)]; // dimensions of attribute adims[0] = static_cast(3); // datapoints in attibute dimension 0 - aspace = H5Screate_simple(arank, adims, nullptr); // dataspace for attribute + aspace = H5::DataSpace(arank, adims, nullptr); // dataspace for attribute vector = orientation.createAttribute(VECTOR, H5::PredType::NATIVE_DOUBLE, aspace); // attribute vector vector.write(H5::PredType::NATIVE_DOUBLE, @@ -699,17 +698,17 @@ class NexusGeometrySaveImpl { // neither orientation nor location are non-zero, NXsource is self // dependent. if (!locationIsOrigin) { - dependency = H5_OBJ_NAME(transformations) + "/" + LOCATION; + dependency = transformations.getObjName() + "/" + LOCATION; writeLocation(transformations, position); } if (!orientationIsZero) { - dependency = H5_OBJ_NAME(transformations) + "/" + ORIENTATION; + dependency = transformations.getObjName() + "/" + ORIENTATION; // If location dataset is written to group also, then dependency for // orientation dataset containg the rotation transformation will be // location. Else dependency for orientation is self. std::string rotationDependency = - locationIsOrigin ? NO_DEPENDENCY : H5_OBJ_NAME(transformations) + "/" + LOCATION; + locationIsOrigin ? NO_DEPENDENCY : transformations.getObjName() + "/" + LOCATION; writeOrientation(transformations, rotation, rotationDependency); } } @@ -762,17 +761,17 @@ class NexusGeometrySaveImpl { // If neither orientation nor location are non-zero, NXmonitor is self // dependent. if (!locationIsOrigin) { - dependency = H5_OBJ_NAME(transformations) + "/" + LOCATION; + dependency = transformations.getObjName() + "/" + LOCATION; writeLocation(transformations, position); } if (!orientationIsZero) { - dependency = H5_OBJ_NAME(transformations) + "/" + ORIENTATION; + dependency = transformations.getObjName() + "/" + ORIENTATION; // If location dataset is written to group also, then dependency for // orientation dataset containg the rotation transformation will be // location. Else dependency for orientation is self. std::string rotationDependency = - locationIsOrigin ? NO_DEPENDENCY : H5_OBJ_NAME(transformations) + "/" + LOCATION; + locationIsOrigin ? NO_DEPENDENCY : transformations.getObjName() + "/" + LOCATION; writeOrientation(transformations, rotation, rotationDependency); } } @@ -859,17 +858,17 @@ class NexusGeometrySaveImpl { // If neither orientation nor location are non-zero, NXdetector is self // dependent. if (!locationIsOrigin) { - dependency = H5_OBJ_NAME(transformations) + "/" + LOCATION; + dependency = transformations.getObjName() + "/" + LOCATION; writeLocation(transformations, position); } if (!orientationIsZero) { - dependency = H5_OBJ_NAME(transformations) + "/" + ORIENTATION; + dependency = transformations.getObjName() + "/" + ORIENTATION; // If location dataset is written to group also, then dependency for // orientation dataset containing the rotation transformation will be // location. Else dependency for orientation is self. std::string rotationDependency = - locationIsOrigin ? NO_DEPENDENCY : H5_OBJ_NAME(transformations) + "/" + LOCATION; + locationIsOrigin ? NO_DEPENDENCY : transformations.getObjName() + "/" + LOCATION; writeOrientation(transformations, rotation, rotationDependency); } } diff --git a/Framework/NexusGeometry/src/NexusGeometryUtilities.cpp b/Framework/NexusGeometry/src/NexusGeometryUtilities.cpp index 895ab36768ae..7a1907c7ba37 100644 --- a/Framework/NexusGeometry/src/NexusGeometryUtilities.cpp +++ b/Framework/NexusGeometry/src/NexusGeometryUtilities.cpp @@ -5,7 +5,6 @@ // Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS // SPDX - License - Identifier: GPL - 3.0 + #include "MantidNexusGeometry/NexusGeometryUtilities.h" -#include "MantidNexusGeometry/H5ForwardCompatibility.h" #include "MantidNexusGeometry/NexusGeometryDefinitions.h" #include namespace Mantid::NexusGeometry::utilities { @@ -66,7 +65,7 @@ bool hasNXClass(const H5::Group &group, const std::string &attributeValue) { } bool isNamed(const H5::H5Object &object, const std::string &name) { - const auto objName = H5_OBJ_NAME(object); + const auto objName = object.getObjName(); // resultName gives full path. We match the last name on the path return std::regex_match(objName, std::regex(".*/" + name + "$")); } diff --git a/Framework/TestHelpers/inc/MantidFrameworkTestHelpers/NexusFileReader.h b/Framework/TestHelpers/inc/MantidFrameworkTestHelpers/NexusFileReader.h index e5371d3da181..47a6cb3b6827 100644 --- a/Framework/TestHelpers/inc/MantidFrameworkTestHelpers/NexusFileReader.h +++ b/Framework/TestHelpers/inc/MantidFrameworkTestHelpers/NexusFileReader.h @@ -6,7 +6,6 @@ // SPDX - License - Identifier: GPL - 3.0 + #pragma once -#include "MantidNexusGeometry/H5ForwardCompatibility.h" #include "MantidNexusGeometry/NexusGeometryDefinitions.h" #include From 70ca9e48da990965773fdb2410bd81f4273345e0 Mon Sep 17 00:00:00 2001 From: Ross Whitfield Date: Tue, 21 Jan 2025 10:34:13 +1100 Subject: [PATCH 5/9] Update NexusHDF5Descriptor --- Framework/Kernel/src/NexusHDF5Descriptor.cpp | 157 +++---------------- 1 file changed, 26 insertions(+), 131 deletions(-) diff --git a/Framework/Kernel/src/NexusHDF5Descriptor.cpp b/Framework/Kernel/src/NexusHDF5Descriptor.cpp index dfe20186ee02..dde98bce2d1e 100644 --- a/Framework/Kernel/src/NexusHDF5Descriptor.cpp +++ b/Framework/Kernel/src/NexusHDF5Descriptor.cpp @@ -10,8 +10,7 @@ #include #include "MantidKernel/NexusDescriptor.h" - -#include +#include #include // malloc, calloc #include // strcpy @@ -26,144 +25,43 @@ namespace Mantid::Kernel { /// PRIVATE namespace { -/** - * populate a string attribute from HDF5 attribute handler - * @param attr input HDF5 atttribute handler - * @param data - * @return - */ -herr_t readStringAttribute(hid_t attr, char **data) { - herr_t iRet = 0; - hsize_t thedims[H5S_MAX_RANK]; - - hid_t atype = H5Aget_type(attr); - hsize_t sdim = H5Tget_size(atype); - hid_t space = H5Aget_space(attr); - int ndims = H5Sget_simple_extent_dims(space, thedims, NULL); - - if (ndims == 0) { - if (H5Tis_variable_str(atype)) { - hid_t btype = H5Tget_native_type(atype, H5T_DIR_ASCEND); - iRet = H5Aread(attr, btype, data); - H5Tclose(btype); - } else { - *data = (char *)malloc(sdim + 1); - iRet = H5Aread(attr, atype, *data); - (*data)[sdim] = '\0'; - } - } else if (ndims == 1) { - unsigned int i; - char **strings; - - strings = (char **)malloc(thedims[0] * sizeof(char *)); - - if (!H5Tis_variable_str(atype)) { - strings[0] = (char *)malloc(thedims[0] * sdim * sizeof(char)); - for (i = 1; i < thedims[0]; i++) { - strings[i] = strings[0] + i * sdim; - } - } - - iRet = H5Aread(attr, atype, strings[0]); - *data = (char *)calloc((sdim + 2) * thedims[0], sizeof(char)); - for (i = 0; i < thedims[0]; i++) { - if (i == 0) { - strncpy(*data, strings[i], sdim); - } else { - strcat(*data, ", "); - strncat(*data, strings[i], sdim); - } - } - if (H5Tis_variable_str(atype)) { - H5Dvlen_reclaim(atype, space, H5P_DEFAULT, strings); - } else { - free(strings[0]); - } - - free(strings); - } else { - *data = (char *)malloc(33); - strcpy(*data, " higher dimensional string array\0"); - } - - H5Tclose(atype); - H5Sclose(space); - if (iRet < 0) - return -1; - return 0; -} - -/** - * Reads a string attribute of N-dimensions - * @param attr input HDF5 attribute handler - * @return - */ -std::pair readStringAttributeN(hid_t attr) { - char *vdat = NULL; - const auto iRet = readStringAttribute(attr, &vdat); - std::string attrData; - if (iRet >= 0) { - attrData = vdat; - } - free(vdat); - return std::make_pair(attrData, iRet); -} - -void getGroup(hid_t groupID, std::map> &allEntries) { +void getGroup(H5::Group groupID, std::map> &allEntries) { /** * Return the NX_class attribute associate with objectName group entry */ - auto lf_getNxClassAttribute = [&](hid_t groupID, const char *objectName) -> std::string { + auto lf_getNxClassAttribute = [&](H5::Group groupID) -> std::string { std::string attribute = ""; - hid_t attributeID = H5Aopen_by_name(groupID, objectName, "NX_class", H5P_DEFAULT, H5P_DEFAULT); - if (attributeID < 0) { - H5Aclose(attributeID); - return attribute; - } - auto pairData = readStringAttributeN(attributeID); - // already null terminated in readStringAttributeN - attribute = pairData.first; - H5Aclose(attributeID); + if (groupID.attrExists("NX_class")) { + const auto attributeID = groupID.openAttribute("NX_class"); + attributeID.read(attributeID.getDataType(), attribute); + } return attribute; }; - // using HDF5 C API - constexpr std::size_t maxLength = 1024; - char groupName[maxLength]; - char memberName[maxLength]; - std::size_t groupNameLength = static_cast(H5Iget_name(groupID, groupName, maxLength)); - hsize_t nObjects = 0; - H5Gget_num_objs(groupID, &nObjects); - - const std::string groupNameStr(groupName, groupNameLength); - const std::string nxClass = (groupNameStr == "/") ? "" : lf_getNxClassAttribute(groupID, groupNameStr.c_str()); + // using HDF5 C++ API + const std::string groupNameStr = groupID.getObjName(); + const std::string nxClass = (groupNameStr == "/") ? "" : lf_getNxClassAttribute(groupID); if (!nxClass.empty()) { allEntries[nxClass].insert(groupNameStr); } - for (unsigned int i = 0; i < nObjects; ++i) { + for (hsize_t i = 0; i < groupID.getNumObjs(); ++i) { - const int type = H5Gget_objtype_by_idx(groupID, static_cast(i)); - const std::size_t memberNameLength = - static_cast(H5Gget_objname_by_idx(groupID, static_cast(i), memberName, maxLength)); - - if (type == H5O_TYPE_GROUP) { - hid_t subGroupID = H5Gopen2(groupID, memberName, H5P_DEFAULT); + H5G_obj_t type = groupID.getObjTypeByIdx(i); + H5std_string memberName = groupID.getObjnameByIdx(i); + if (type == H5G_GROUP) { + H5::Group subGroupID = groupID.openGroup(memberName); getGroup(subGroupID, allEntries); - H5Gclose(subGroupID); - - } else if (type == H5O_TYPE_DATASET) { - const std::string memberNameStr(memberName, memberNameLength); - const std::string absoluteEntryName = groupNameStr + "/" + memberNameStr; + } else if (type == H5G_DATASET) { + const std::string absoluteEntryName = groupNameStr + "/" + memberName; allEntries["SDS"].insert(absoluteEntryName); } } } - } // namespace bool NexusHDF5Descriptor::isReadable(const std::string &filename) { @@ -183,24 +81,21 @@ const std::map> &NexusHDF5Descriptor::getAllE // PRIVATE std::map> NexusHDF5Descriptor::initAllEntries() { - - hid_t fapl = H5Pcreate(H5P_FILE_ACCESS); - H5Pset_fclose_degree(fapl, H5F_CLOSE_STRONG); - - hid_t fileID = H5Fopen(m_filename.c_str(), H5F_ACC_RDONLY, fapl); - if (fileID < 0) { - - throw std::invalid_argument("ERROR: Kernel::NexusHDF5Descriptor couldn't open hdf5 file " + m_filename + - " with fapl " + std::to_string(fapl) + "\n"); + H5::FileAccPropList access_plist; + access_plist.setFcloseDegree(H5F_CLOSE_STRONG); + + H5::H5File fileID; + try { + fileID = H5::H5File(m_filename, H5F_ACC_RDONLY, H5::FileCreatPropList::DEFAULT, access_plist); + } catch (const H5::FileIException &) { + throw std::invalid_argument("ERROR: Kernel::NexusHDF5Descriptor couldn't open hdf5 file " + m_filename + "\n"); } - hid_t groupID = H5Gopen2(fileID, "/", H5P_DEFAULT); + H5::Group groupID = fileID.openGroup("/"); std::map> allEntries; // scan file recursively starting with root group "/" getGroup(groupID, allEntries); - H5Gclose(groupID); - H5Fclose(fileID); // rely on move semantics return allEntries; From 143249f8a7243a66be37d877f222ce32878334ef Mon Sep 17 00:00:00 2001 From: Ross Whitfield Date: Tue, 21 Jan 2025 13:19:50 +1100 Subject: [PATCH 6/9] Update CppCheck_Suppressions --- buildconfig/CMake/CppCheck_Suppressions.txt.in | 5 ----- 1 file changed, 5 deletions(-) diff --git a/buildconfig/CMake/CppCheck_Suppressions.txt.in b/buildconfig/CMake/CppCheck_Suppressions.txt.in index 36fe47cfe509..ac473e16c11e 100644 --- a/buildconfig/CMake/CppCheck_Suppressions.txt.in +++ b/buildconfig/CMake/CppCheck_Suppressions.txt.in @@ -826,11 +826,6 @@ truncLongCastAssignment:${CMAKE_SOURCE_DIR}/Framework/Kernel/src/Matrix.cpp:1021 suspiciousFloatingPointCast:${CMAKE_SOURCE_DIR}/Framework/Kernel/src/Matrix.cpp:1205 iterateByValue:${CMAKE_SOURCE_DIR}/Framework/Kernel/src/MultiFileValidator.cpp:65 constVariablePointer:${CMAKE_SOURCE_DIR}/Framework/Kernel/src/NeutronAtom.cpp:713 -cstyleCast:${CMAKE_SOURCE_DIR}/Framework/Kernel/src/NexusHDF5Descriptor.cpp:50 -cstyleCast:${CMAKE_SOURCE_DIR}/Framework/Kernel/src/NexusHDF5Descriptor.cpp:58 -cstyleCast:${CMAKE_SOURCE_DIR}/Framework/Kernel/src/NexusHDF5Descriptor.cpp:61 -cstyleCast:${CMAKE_SOURCE_DIR}/Framework/Kernel/src/NexusHDF5Descriptor.cpp:68 -cstyleCast:${CMAKE_SOURCE_DIR}/Framework/Kernel/src/NexusHDF5Descriptor.cpp:85 variableScope:${CMAKE_SOURCE_DIR}/Framework/Kernel/src/PropertyManager.cpp:113 invalidLifetime:${CMAKE_SOURCE_DIR}/Framework/Kernel/src/PropertyManager.cpp:142 constVariablePointer:${CMAKE_SOURCE_DIR}/Framework/Kernel/src/PropertyManager.cpp:158 From 5ad9c14593ebc5ce6f41a5165f0c2997ce4306f3 Mon Sep 17 00:00:00 2001 From: Ross Whitfield Date: Tue, 21 Jan 2025 14:08:03 +1100 Subject: [PATCH 7/9] Fix error: reference to 'Exception' is ambiguous --- Framework/DataHandling/test/LoadNexusProcessedTest.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Framework/DataHandling/test/LoadNexusProcessedTest.h b/Framework/DataHandling/test/LoadNexusProcessedTest.h index a6cb5421bcf4..6c3e14a184b8 100644 --- a/Framework/DataHandling/test/LoadNexusProcessedTest.h +++ b/Framework/DataHandling/test/LoadNexusProcessedTest.h @@ -49,8 +49,6 @@ using namespace Mantid::HistogramData; using namespace Mantid::NeXus; using Mantid::detid_t; -using namespace H5; - // Note that this suite tests an old version of Nexus processed files that we // continue to support. // LoadRawSaveNxsLoadNxs tests the current version of Nexus processed by loading @@ -801,7 +799,7 @@ class LoadNexusProcessedTest : public CxxTest::TestSuite { // Remove the coordinate_system entry so it falls back on the log. NeXus // can't do this so use the HDF5 API directly - H5File h5file(filePath.c_str(), H5F_ACC_RDWR); + H5::H5File h5file(filePath.c_str(), H5F_ACC_RDWR); H5Util::deleteObjectLink(h5file, "/mantid_workspace_1/peaks_workspace/coordinate_system"); h5file.close(); From 48d482b7ff6a9efe0ccc2d79b21f384d191bf5b6 Mon Sep 17 00:00:00 2001 From: Ross Whitfield Date: Tue, 21 Jan 2025 16:02:10 +1100 Subject: [PATCH 8/9] Fix unreferenced local variable warning --- Framework/DataHandling/src/LoadSassena.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Framework/DataHandling/src/LoadSassena.cpp b/Framework/DataHandling/src/LoadSassena.cpp index 23eb94d0705d..acb2043c1dcf 100644 --- a/Framework/DataHandling/src/LoadSassena.cpp +++ b/Framework/DataHandling/src/LoadSassena.cpp @@ -101,7 +101,7 @@ HistogramData::Points LoadSassena::loadQvectors(const H5::H5File &h5file, const hsize_t dims[3]; try { dataSetInfo(h5file, setName, dims); - } catch (H5::Exception &e) { + } catch (H5::Exception &) { throw Kernel::Exception::FileError("Unable to read " + setName + " dataset info:", m_filename); } @@ -110,7 +110,7 @@ HistogramData::Points LoadSassena::loadQvectors(const H5::H5File &h5file, const try { this->dataSetDouble(h5file, "qvectors", buf); - } catch (H5::Exception &e) { + } catch (H5::Exception &) { this->g_log.error("LoadSassena::loadQvectors cannot proceed"); qvmod.resize(0); return HistogramData::Points(std::move(qvmod)); @@ -169,7 +169,7 @@ void LoadSassena::loadFQ(const H5::H5File &h5file, const API::WorkspaceGroup_spt std::vector buf(nq * 2); try { this->dataSetDouble(h5file, setName, buf); - } catch (H5::Exception &e) { + } catch (H5::Exception &) { this->g_log.error("LoadSassena::loadFQ cannot proceed"); return; } @@ -229,7 +229,7 @@ void LoadSassena::loadFQT(const H5::H5File &h5file, const API::WorkspaceGroup_sp std::vector buf(nq * nnt * 2); try { this->dataSetDouble(h5file, setName, buf); - } catch (H5::Exception &e) { + } catch (H5::Exception &) { this->g_log.error("LoadSassena::loadFQT cannot proceed"); return; } @@ -356,7 +356,7 @@ void LoadSassena::exec() { H5::H5File h5file; try { h5file = H5::H5File(m_filename.c_str(), H5F_ACC_RDONLY); - } catch (H5::FileIException &e) { + } catch (H5::FileIException &) { this->g_log.error("Cannot open " + m_filename); throw Kernel::Exception::FileError("Unable to open:", m_filename); } From 3359aa9b32c1ba8469784aa88d048bcb2a9b4e36 Mon Sep 17 00:00:00 2001 From: Ross Whitfield Date: Wed, 22 Jan 2025 08:19:12 +1100 Subject: [PATCH 9/9] this --- Framework/DataHandling/src/LoadSassena.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Framework/DataHandling/src/LoadSassena.cpp b/Framework/DataHandling/src/LoadSassena.cpp index acb2043c1dcf..f7510cee7f22 100644 --- a/Framework/DataHandling/src/LoadSassena.cpp +++ b/Framework/DataHandling/src/LoadSassena.cpp @@ -100,7 +100,7 @@ HistogramData::Points LoadSassena::loadQvectors(const H5::H5File &h5file, const hsize_t dims[3]; try { - dataSetInfo(h5file, setName, dims); + this->dataSetInfo(h5file, setName, dims); } catch (H5::Exception &) { throw Kernel::Exception::FileError("Unable to read " + setName + " dataset info:", m_filename); } @@ -216,7 +216,7 @@ void LoadSassena::loadFQT(const H5::H5File &h5file, const API::WorkspaceGroup_sp hsize_t dims[3]; try { - dataSetInfo(h5file, setName, dims); + this->dataSetInfo(h5file, setName, dims); } catch (H5::Exception &) { this->g_log.error("Unable to read " + setName + " dataset info"); this->g_log.error("LoadSassena::loadFQT cannot proceed");