From 4c3a40c7d7eecd1edf20e9e561074b1966135fd9 Mon Sep 17 00:00:00 2001 From: Sam Cunliffe Date: Tue, 7 Feb 2023 11:02:21 +0000 Subject: [PATCH] Passes first tests! #181 --- tdms/include/hdf5_io.h | 44 ++++++++++++++++++++++++++------ tdms/src/hdf5_io.cpp | 43 ++++++++++++++++--------------- tdms/tests/unit/test_hdf5_io.cpp | 12 +++++++-- 3 files changed, 68 insertions(+), 31 deletions(-) diff --git a/tdms/include/hdf5_io.h b/tdms/include/hdf5_io.h index e45047bd2..323cb526d 100644 --- a/tdms/include/hdf5_io.h +++ b/tdms/include/hdf5_io.h @@ -6,13 +6,13 @@ */ #pragma once -// std #include #include #include +#include -// libhdf5 #include +#include /** * @brief The base class for HDF5 I/O. @@ -32,8 +32,7 @@ class HDF5Base { * HDF5Writer.) * @throws H5::FileIException if the file doesn't exist or can't be created. */ - HDF5Base(const std::string &filename, int mode = H5F_ACC_RDONLY) - : filename_(filename) { + HDF5Base(const std::string &filename, int mode = H5F_ACC_RDONLY) : filename_(filename) { file_ = std::make_unique(filename, mode); } @@ -106,8 +105,38 @@ class HDF5Reader : public HDF5Base { * @param dataname The name of the datset to be read. * @param data A pointer to an array of correct size. */ - template - void read(const std::string &dataname, T *data) const; + //template + //void read(const std::string &dataname, T *data) const; + template + void read(const std::string &dataset_name, T *data) const { + spdlog::debug("Reading {} from file: {}", dataset_name, filename_); + + // get the dataset and dataspace (contains dimensionality info) + H5::DataSet dataset = file_->openDataSet(dataset_name); + H5::DataSpace dataspace = dataset.getSpace(); + spdlog::debug("Created dataspace"); + + // need to get the number of matrix dimensions (rank) so that we can + // dynamically allocate `dimensions` + int rank = dataspace.getSimpleExtentNdims(); + spdlog::debug("Rank of dataspace: {}", rank); + hsize_t *dimensions = new hsize_t[rank]; + dataspace.getSimpleExtentDims(dimensions); + spdlog::debug("Got dimensions"); + + //auto dimensions = shape_of(dataset_name); + // TODO why do we need `dimensions` at all here? + + // now get the data type + H5::DataType datatype = dataset.getDataType(); + spdlog::debug("Got datatype"); + // std::cout << datatype.getObjName() << std::endl; + // + dataset.read(data, datatype); + spdlog::debug("Read"); + + delete[] dimensions; + } }; class HDF5Writer : public HDF5Base { @@ -127,6 +156,5 @@ class HDF5Writer : public HDF5Base { * @param size The size of the data array. * @param dimensions The number of dimensions of the array. */ - void write(const std::string &dataname, double *data, int size, - hsize_t *dimensions); + void write(const std::string &dataname, double *data, int size, hsize_t *dimensions); }; diff --git a/tdms/src/hdf5_io.cpp b/tdms/src/hdf5_io.cpp index 2a956c335..0c57f37a7 100644 --- a/tdms/src/hdf5_io.cpp +++ b/tdms/src/hdf5_io.cpp @@ -3,49 +3,50 @@ #include #include +#include /****************************************************************************** * HDF5Reader */ -template -void HDF5Reader::read(const std::string &dataset_name, T *data) const { +// template +// void HDF5Reader::read(const std::string &dataset_name, T *data) const { +// spdlog::debug("Reading {} from file: {}", dataset_name, filename_); - // get the dataset and dataspace (contains dimensionality info) - H5::DataSet dataset = file_->openDataSet(dataset_name); - H5::DataSpace dataspace = dataset.getSpace(); +// // get the dataset and dataspace (contains dimensionality info) +// H5::DataSet dataset = file_->openDataSet(dataset_name); +// H5::DataSpace dataspace = dataset.getSpace(); - // need to get the number of matrix dimensions (rank) so that we can - // dynamically allocate `dimensions` - int rank = dataspace.getSimpleExtentNdims(); - hsize_t *dimensions = new hsize_t[rank]; - dataspace.getSimpleExtentDims(dimensions); +// // need to get the number of matrix dimensions (rank) so that we can +// // dynamically allocate `dimensions` +// int rank = dataspace.getSimpleExtentNdims(); +// hsize_t *dimensions = new hsize_t[rank]; +// dataspace.getSimpleExtentDims(dimensions); - //auto dimensions = shape_of(dataset_name); - // TODO why do we need `dimensions` at all here? +// //auto dimensions = shape_of(dataset_name); +// // TODO why do we need `dimensions` at all here? - // now get the data type - H5::DataType datatype = dataset.getDataType(); - dataset.read(data, datatype); +// // now get the data type +// H5::DataType datatype = dataset.getDataType(); +// dataset.read(data, datatype); - delete[] dimensions; -} +// delete[] dimensions; +// } /****************************************************************************** * HDF5Writer */ void HDF5Writer::write(const std::string &dataset_name, double *data, int size, hsize_t *dimensions) { - // 1D array - hsize_t rank = 1; - (void) size;// TODO what? + spdlog::debug("Writing {} to file: {}", dataset_name, filename_); // declare a dataspace - H5::DataSpace dataspace(rank, dimensions); + H5::DataSpace dataspace(size, dimensions); H5::DataType datatype(H5::PredType::NATIVE_DOUBLE); // write the data to the dataset object in the file H5::DataSet dataset = file_->createDataSet(dataset_name, datatype, dataspace); dataset.write(data, H5::PredType::NATIVE_DOUBLE); + spdlog::trace("Write successful."); } /****************************************************************************** diff --git a/tdms/tests/unit/test_hdf5_io.cpp b/tdms/tests/unit/test_hdf5_io.cpp index 125ada147..94a238c74 100644 --- a/tdms/tests/unit/test_hdf5_io.cpp +++ b/tdms/tests/unit/test_hdf5_io.cpp @@ -49,16 +49,23 @@ TEST_CASE("Test file I/O construction/destruction.") { // create a file { HDF5Writer fw(tmp.string() + "/test_file_wr.h5"); + hsize_t dimensions[1] = {1}; double writeme = 1337.; - fw.write("testdata", &writeme, 1, (hsize_t*)1); + fw.write("testdata", &writeme, 1, dimensions); + spdlog::debug("Written data"); + CHECK(fw.is_ok()); + fw.ls(); }// destructor called as we leave scope + double data[1]; HDF5Reader fr(tmp.string() + "/test_file_wr.h5"); - //fr.read("testdata"); + fr.read("testdata", data); + spdlog::debug("Have read {}!", data[0]); } + /* SECTION("Check write then (overwrite) then read.") { // Create the file and write some data. @@ -85,6 +92,7 @@ TEST_CASE("Test file I/O construction/destruction.") { //CHECK_NOTHROW(f3.read()); //CHECK_THROWS(f3.read()); } + */ // teardown - remove temporary directory and all files SPDLOG_DEBUG("Removing temporary directory.");