diff --git a/sample/testHDF5.cpp b/sample/testHDF5.cpp index ab08c98..4121f5a 100644 --- a/sample/testHDF5.cpp +++ b/sample/testHDF5.cpp @@ -87,7 +87,7 @@ int main() H5::Group g = f.createGroup("test_group"); array_type A(boost::extents[2][3]); - array_type B; + array_type B, Bprime(boost::extents[1][2]); array3_type C(boost::extents[2][3][4]); arrayc_type D, E; array_mys_type F(boost::extents[10]), G; @@ -130,6 +130,7 @@ int main() abort(); } + std::cout << "Testing C " << std::endl; try { CosmoTool::hdf5_read_array(g, "test_data", C); @@ -138,6 +139,23 @@ int main() } catch (const CosmoTool::InvalidDimensions&) {} + + std::cout << "Testing Bprime " << std::endl; + try + { + CosmoTool::hdf5_read_array(g, "test_data", Bprime, false, true); + for (index i = 0; i != 1; i++) + for (index j = 0; j != 2; j++) + if (B[i][j] != Bprime[i][j]) { + std::cout << "Invalid array content in Bprime" << endl; + abort(); + } + } + catch (const CosmoTool::InvalidDimensions&) + { + std::cout << "Bad! Dimensions should be accepted" << std::endl; + abort(); + } D.resize(boost::extents[2][3]); D = A; diff --git a/src/hdf5_array.hpp b/src/hdf5_array.hpp index 1d8b2a4..c164f4e 100644 --- a/src/hdf5_array.hpp +++ b/src/hdf5_array.hpp @@ -283,6 +283,20 @@ namespace CosmoTool { } } + template + void hdf5_weak_check_array(ArrayType& data, std::vector& dims) { + for (long i = 0; i < data.num_dimensions(); i++) { + if (data.index_bases()[i] < 0) { + // Negative indexes are not supported right now. + throw InvalidDimensions(); + } + if (data.index_bases()[i]+data.shape()[i] > dims[i]) { + throw InvalidDimensions(); + } + } + } + + template typename boost::disable_if< array_has_resize @@ -296,7 +310,7 @@ namespace CosmoTool { template void hdf5_read_array_typed(H5::CommonFG& fg, const std::string& data_set_name, ArrayType& data, - const hdf5_data_type& datatype, bool auto_resize = true) + const hdf5_data_type& datatype, bool auto_resize = true, bool useBases = false) { H5::DataSet dataset = fg.openDataSet(data_set_name); H5::DataSpace dataspace = dataset.getSpace(); @@ -310,18 +324,31 @@ namespace CosmoTool { dataspace.getSimpleExtentDims(dimensions.data()); if (auto_resize) hdf5_resize_array(data, dimensions); - else - hdf5_check_array(data, dimensions); - + else { + if (useBases) { + hdf5_weak_check_array(data, dimensions); + + std::vector memdims(data.shape(), data.shape() + data.num_dimensions()); + H5::DataSpace memspace(memdims.size(), memdims.data()); + + std::vector offsets(data.index_bases(), data.index_bases() + data.num_dimensions()); + dataspace.selectHyperslab(H5S_SELECT_SET, memdims.data(), offsets.data()); + + dataset.read(data.data(), datatype, memspace, dataspace); + } else { + hdf5_check_array(data, dimensions); + } + } dataset.read(data.data(), datatype); } template - void hdf5_read_array(H5::CommonFG& fg, const std::string& data_set_name, ArrayType& data, bool auto_resize = true ) + void hdf5_read_array(H5::CommonFG& fg, const std::string& data_set_name, ArrayType& data, bool auto_resize = true, + bool useBases = false ) { typedef typename ArrayType::element T; - hdf5_read_array_typed(fg, data_set_name, data, get_hdf5_data_type::type(), auto_resize); + hdf5_read_array_typed(fg, data_set_name, data, get_hdf5_data_type::type(), auto_resize, useBases); }