Skip to content

Commit

Permalink
feat(Python): Add Pyodide PointSet support
Browse files Browse the repository at this point in the history
  • Loading branch information
thewtex committed Apr 19, 2023
1 parent 4247bbd commit f8d0fa3
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 6 deletions.
24 changes: 21 additions & 3 deletions packages/core/python/itkwasm/itkwasm/pyodide.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,20 +64,38 @@ def to_py(js_proxy):
import pyodide
if hasattr(js_proxy, "imageType"):
image_dict = js_proxy.to_py()
image_type = image_dict['imageType']
dimension = image_type['dimension']
component_type = image_type['componentType']
image_type = ImageType(**image_dict['imageType'])
image_dict['imageType'] = image_type
dimension = image_type.dimension
component_type = image_type.componentType
image_dict['direction'] = _to_numpy_array(str(FloatTypes.Float64), image_dict['direction']).reshape((dimension, dimension))
image_dict['data'] = _to_numpy_array(component_type, image_dict['data']).reshape((dimension, dimension))
return Image(**image_dict)
elif hasattr(js_proxy, "pointSetType"):
point_set_dict = js_proxy.to_py()
point_set_type = PointSetType(**point_set_dict['pointSetType'])
point_set_dict['pointSetType'] = point_set_type
dimension = point_set_type.dimension
point_component_type = point_set_type.pointComponentType
point_pixel_component_type = point_set_type.pointPixelComponentType
point_set_dict['points'] = _to_numpy_array(point_component_type, point_set_dict['points']).reshape((-1, dimension))
point_set_dict['pointData'] = _to_numpy_array(point_pixel_component_type, point_set_dict['pointData'])
return PointSet(**point_set_dict)
return js_proxy.to_py()

def to_js(py):
import pyodide
import js
if isinstance(py, Image):
image_dict = asdict(py)
print('to_js image dict', image_dict['imageType'])
image_dict['direction'] = image_dict['direction'].ravel()
image_dict['data'] = image_dict['data'].ravel()
return pyodide.ffi.to_js(image_dict, dict_converter=js.Object.fromEntries)
elif isinstance(py, PointSet):
point_set_dict = asdict(py)
point_set_dict['points'] = point_set_dict['points'].ravel()
point_set_dict['pointData'] = point_set_dict['pointData'].ravel()
return pyodide.ffi.to_js(point_set_dict, dict_converter=js.Object.fromEntries)

return py
4 changes: 2 additions & 2 deletions packages/core/python/itkwasm/test/test_pointset.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ def test_pointset():

point_data = np.random.random((n_points,)).astype(np.float32)
pointset.SetPointData(itk.vector_container_from_array(point_data.ravel()))

itk_pointset_dict = itk.dict_from_pointset(pointset)
# Bug, to be fixed by 5.3.0
itk_pointset_dict.pop('dimension', None)
itkwasm_pointset = PointSet(**itk_pointset_dict)
itkwasm_pointset_dict = asdict(itkwasm_pointset)
itk_pointset_roundtrip = itk.pointset_from_dict(itkwasm_pointset_dict)
itk_pointset_roundtrip_dict = itk.dict_from_pointset(itk_pointset_roundtrip)

pointSetType = itk_pointset_dict["pointSetType"]
pointSetType_roundtrip = itk_pointset_roundtrip_dict["pointSetType"]
assert pointSetType["dimension"] == pointSetType_roundtrip["dimension"]
Expand Down
37 changes: 36 additions & 1 deletion packages/core/python/itkwasm/test/test_pyodide.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,39 @@ async def test_image_conversion(selenium, package_wheel):
assert image_py.size[1] == 2

assert isinstance(image_py.metadata, dict)
assert np.array_equal(image_py.data, np.arange(4, dtype=np.uint8).reshape((2,2)))
assert np.array_equal(image_py.data, np.arange(4, dtype=np.uint8).reshape((2,2)))

@run_in_pyodide(packages=['micropip', 'numpy'])
async def test_point_set_conversion(selenium, package_wheel):
import micropip
await micropip.install(package_wheel)

from itkwasm import PointSet, PointSetType, PixelTypes, FloatTypes
from itkwasm.pyodide import to_js, to_py
import numpy as np

n_points = 5
dimension = 3

points = np.random.random((n_points, dimension)).astype(np.float32)
point_data = np.random.random((n_points,)).astype(np.float32)

point_set_type = PointSetType(dimension, FloatTypes.Float32, FloatTypes.Float32, PixelTypes.Scalar, FloatTypes.Float32)

point_set = PointSet(point_set_type, 'point_set', n_points, points, n_points, point_data)

point_set_js = to_js(point_set)
point_set_py = to_py(point_set_js)

point_set_type_py = point_set_py.pointSetType
assert point_set_type.dimension == point_set_type_py.dimension
assert point_set_type.pointComponentType == point_set_type_py.pointComponentType
assert point_set_type.pointPixelComponentType == point_set_type_py.pointPixelComponentType
assert point_set_type.pointPixelType == point_set_type_py.pointPixelType
assert point_set_type.pointPixelComponents == point_set_type_py.pointPixelComponents

assert point_set.name == point_set_py.name
assert point_set.numberOfPoints == point_set_py.numberOfPoints
assert np.array_equal(point_set.points, point_set_py.points)
assert point_set.numberOfPointPixels == point_set_py.numberOfPointPixels
assert np.array_equal(point_set.pointData, point_set_py.pointData)

0 comments on commit f8d0fa3

Please sign in to comment.