diff --git a/src/cpp/h5cpp/dataspace/selections.cpp b/src/cpp/h5cpp/dataspace/selections.cpp index 2dbb065d..a2dfb4f2 100644 --- a/src/cpp/h5cpp/dataspace/selections.cpp +++ b/src/cpp/h5cpp/dataspace/selections.cpp @@ -64,6 +64,64 @@ hdf5::Dimensions get_block(const hdf5::dataspace::Hyperslab &self) } // anonymous namespace + +// hdf5::Dimensions get_points_dimensions(const hdf5::dataspace::Points &self) +// { +// return self.dimensions(); +// } + +std::vector> get_coord_set(boost::python::list coord_set){ + + std::vector> coords; + + for (boost::python::ssize_t i = 0, iend = len(coord_set); i < iend; ++i){ + std::vector crd; + boost::python::list coord(coord_set[i]); + for (boost::python::ssize_t j = 0, jend = len(coord); j < jend; ++j){ + boost::python::object o = coord[j]; + boost::python::extract s(o); + if (s.check()){ + crd.push_back(s()); + } + } + coords.push_back(crd); + } + return coords; +} + +std::vector get_coords(boost::python::list coords){ + + std::vector crd; + + for (boost::python::ssize_t j = 0, jend = len(coords); j < jend; ++j){ + boost::python::object o = coords[j]; + boost::python::extract s(o); + if (s.check()){ + crd.push_back(s()); + } + } + return crd; +} + +class DLL_EXPORT PointsWrapper : public hdf5::dataspace::Points +{ + public: + PointsWrapper(): hdf5::dataspace::Points() + {} + PointsWrapper(size_t rank): hdf5::dataspace::Points(rank) + {} + PointsWrapper(boost::python::list coord_set): + hdf5::dataspace::Points(get_coord_set(coord_set)) + {} + void add_set(boost::python::list coord_set){ + hdf5::dataspace::Points::add_set(get_coord_set(coord_set)); + } + void add(boost::python::list coords){ + hdf5::dataspace::Points::add(get_coords(coords)); + } +}; + + void create_selections() { using namespace boost::python; @@ -125,6 +183,15 @@ void create_selections() .def("block",set_individual_block) ; + class_>("Points") + .def(init(args("coord_set"))) + .add_property("rank",&PointsWrapper::rank) + .add_property("size",&PointsWrapper::size) + .add_property("type",&PointsWrapper::type) + .add_property("points",&PointsWrapper::points) + .def("dimensions", &PointsWrapper::dimensions) + ; + class_("View") .def(init((arg("space"),arg("selection")))) .def(init((arg("space")))) diff --git a/src/pninexus/h5cpp/dataspace/__init__.py b/src/pninexus/h5cpp/dataspace/__init__.py index 02c0bcd4..bd3370ab 100644 --- a/src/pninexus/h5cpp/dataspace/__init__.py +++ b/src/pninexus/h5cpp/dataspace/__init__.py @@ -7,10 +7,12 @@ # from .._dataspace import Selection from pninexus.h5cpp._dataspace import SelectionManager from pninexus.h5cpp._dataspace import Hyperslab +from pninexus.h5cpp._dataspace import Points from pninexus.h5cpp._dataspace import SelectionType from pninexus.h5cpp._dataspace import SelectionOperation from pninexus.h5cpp._dataspace import View __all__ = ["Dataspace", "Type", "Simple", "Scalar", "UNLIMITED", "SelectionManager", - "Hyperslab", "SelectionType", "SelectionOperation", "View"] + "Hyperslab", "SelectionType", "SelectionOperation", "View", + "Points"] diff --git a/src/pninexus/h5cpp/node/__init__.py b/src/pninexus/h5cpp/node/__init__.py index a58574a2..b411b9d9 100644 --- a/src/pninexus/h5cpp/node/__init__.py +++ b/src/pninexus/h5cpp/node/__init__.py @@ -229,26 +229,29 @@ def selection_to_shape(selection): """ - if not isinstance(selection, dataspace.Hyperslab): + if isinstance(selection, dataspace.Hyperslab): + shape = [] + size = 1 + for blocks, counts in zip(selection.block(), selection.count()): + size *= blocks * counts + shape.append(blocks * counts) + + if size == 1: + # + # it the total number of elements in the selection is 1 + # the shape is always (1,) + # no matter how many dimension are in the selection. + # + return (1,) + elif len(shape) > 1: + shape = [s for s in shape if s != 1] + + return shape + elif isinstance(selection, dataspace.Points): + return [selection.points] + else: raise TypeError( - "Shape conversion currently only works for Hyperslabs") - - shape = [] - size = 1 - for blocks, counts in zip(selection.block(), selection.count()): - size *= blocks * counts - shape.append(blocks * counts) - - if size == 1: - # - # it the total number of elements in the selection is 1 the shape is - # always (1,) no matter how many dimension are in the selection. - # - return (1,) - elif len(shape) > 1: - shape = [s for s in shape if s != 1] - - return shape + "Shape conversion currently only works for Hyperslabs or Points") def dataset_write(self, data, selection=None): diff --git a/test/h5cpp_tests/node_tests/dataset_partial_io_test.py b/test/h5cpp_tests/node_tests/dataset_partial_io_test.py index 1db4e8fc..ef834b0d 100644 --- a/test/h5cpp_tests/node_tests/dataset_partial_io_test.py +++ b/test/h5cpp_tests/node_tests/dataset_partial_io_test.py @@ -28,7 +28,7 @@ from pninexus.h5cpp.node import Dataset from pninexus.h5cpp.dataspace import Simple # from pninexus.h5cpp.dataspace import Scalar -from pninexus.h5cpp.dataspace import Hyperslab, SelectionType +from pninexus.h5cpp.dataspace import Hyperslab, SelectionType, Points from pninexus.h5cpp.datatype import kInt32 from pninexus.h5cpp.datatype import String from pninexus.h5cpp.property import LinkCreationList @@ -138,11 +138,32 @@ def testWriteReadStrips(self): npt.assert_array_equal( dataset.read(selection=selection), 3 * data_base) - def testWriteReadPoints(self): + def testWriteReadMultiPoints(self): + + dataspace = Simple((5, 3)) + dataset = Dataset( + self.root, h5cpp.Path("WriteReadMultiPoints"), kInt32, dataspace) + + data_base = numpy.ones((3), dtype="int32") + + for i in range(3): + selection = Points([[i, 0], [i + 2, 2], [i + 2, 1]]) + self.assertEqual(selection.rank, 2) + self.assertEqual(selection.size, 3) + self.assertEqual(selection.dimensions(), (2, 3)) + self.assertEqual(selection.type, SelectionType.POINTS) + dataset.write(data_base * (i + 1), selection=selection) + + for i in range(3): + selection = Points([[i, 0], [i + 2, 2], [i + 2, 1]]) + npt.assert_array_equal( + dataset.read(selection=selection), data_base * (i + 1)) + + def testWriteReadHyperPoints(self): dataspace = Simple((3, 5)) dataset = Dataset( - self.root, h5cpp.Path("WriteReadPoints"), kInt32, dataspace) + self.root, h5cpp.Path("WriteReadHyperPoints"), kInt32, dataspace) value = 0 selection = Hyperslab(offset=(0, 0), block=(1, 1)) @@ -160,3 +181,22 @@ def testWriteReadPoints(self): self.assertEqual( dataset.read(selection=selection)[0], value) value += 1 + + def testWriteReadPoints(self): + + dataspace = Simple((3, 5)) + dataset = Dataset( + self.root, h5cpp.Path("WriteReadPoints"), kInt32, dataspace) + + value = 0 + for i in range(3): + for j in range(5): + selection = Points([[i, j]]) + self.assertEqual(selection.rank, 2) + self.assertEqual(selection.size, 1) + self.assertEqual(selection.dimensions(), (1, 1)) + self.assertEqual(selection.type, SelectionType.POINTS) + dataset.write(data=value, selection=selection) + self.assertEqual( + dataset.read(selection=selection)[0], value) + value += 1