KitwareMedical / lungair-desktop-application

Desktop application for AI-based BPD risk analysis
Apache License 2.0
6 stars 5 forks source link

Get access to vtk.util #4

Closed ebrahimebrahim closed 2 years ago

ebrahimebrahim commented 2 years ago

For some reason we do not have access to the vtk.util package, while a typical Slicer build does have it.

e.g.import vtk.util in the console fails

Workaround at the moment is some nasty copy-pasting here-- would be nice to pull those vtk type maps from vtk itself.

jcfr commented 2 years ago

This is also a problem after installing the regular VTK wheel

venv_dir=/tmp/vtk-test

python -m venv $venv_dir

$venv_dir/bin/python --version
Python 3.7.11
$venv_dir/bin/pip install vtk

$venv_dir/bin/python -c "import vtk; print(vtk.__version__)"
9.1.0
$venv_dir/bin/python -c "import vtk;  print('vtk imported'); print(vtk.util)"

vtk imported
Traceback (most recent call last):
  File "<string>", line 1, in <module>
AttributeError: module 'vtkmodules.all' has no attribute 'util'
$venv_dir/bin/python -c "import vtkmodules; print('vtkmodules imported'); print(vtkmodules.util)"

vtkmodules imported
Traceback (most recent call last):
  File "<string>", line 1, in <module>
AttributeError: module 'vtkmodules' has no attribute 'util'
site_packages_dir=$($venv_dir/bin/python -c "import site; print(site.getsitepackages()[0])")
(cd $site_packages_dir; find . | grep -E "vtk.+py$")
./vtkmodules/wx/wxVTKRenderWindow.py
./vtkmodules/wx/wxVTKRenderWindowInteractor.py
./vtkmodules/wx/__init__.py
./vtkmodules/test/ErrorObserver.py
./vtkmodules/test/Testing.py
./vtkmodules/test/BlackBox.py
./vtkmodules/test/__init__.py
./vtkmodules/all.py
./vtkmodules/numpy_interface/internal_algorithms.py
./vtkmodules/numpy_interface/algorithms.py
./vtkmodules/numpy_interface/dataset_adapter.py
./vtkmodules/numpy_interface/__init__.py
./vtkmodules/tk/vtkTkRenderWindowInteractor.py
./vtkmodules/tk/vtkTkImageViewerWidget.py
./vtkmodules/tk/vtkLoadPythonTkWidgets.py
./vtkmodules/tk/vtkTkPhotoImage.py
./vtkmodules/tk/__init__.py
./vtkmodules/tk/vtkTkRenderWidget.py
./vtkmodules/web/dataset_builder.py
./vtkmodules/web/utils.py
./vtkmodules/web/testing.py
./vtkmodules/web/wslink.py
./vtkmodules/web/vtkjs_helper.py
./vtkmodules/web/query_data_model.py
./vtkmodules/web/protocols.py
./vtkmodules/web/__init__.py
./vtkmodules/web/camera.py
./vtkmodules/web/render_window_serializer.py
./vtkmodules/gtk/GtkGLExtVTKRenderWindowInteractor.py
./vtkmodules/gtk/GtkVTKRenderWindowInteractor.py
./vtkmodules/gtk/__init__.py
./vtkmodules/gtk/GtkVTKRenderWindow.py
./vtkmodules/gtk/GtkGLExtVTKRenderWindow.py
./vtkmodules/util/misc.py
./vtkmodules/util/vtkVariant.py
./vtkmodules/util/vtkMethodParser.py
./vtkmodules/util/vtkImageExportToArray.py
./vtkmodules/util/numpy_support.py
./vtkmodules/util/colors.py
./vtkmodules/util/vtkConstants.py
./vtkmodules/util/vtkAlgorithm.py
./vtkmodules/util/__init__.py
./vtkmodules/util/keys.py
./vtkmodules/util/vtkImageImportFromArray.py
./vtkmodules/__init__.py
./vtkmodules/qt/QVTKRenderWindowInteractor.py
./vtkmodules/qt/__init__.py
./vtk.py
jcfr commented 2 years ago

Looking at all.py, it contains the following

# useful macro for getting type names
from .util.vtkConstants import vtkImageScalarTypeNameMacro

# import convenience decorators
from .util.misc import calldata_type

# import the vtkVariant helpers
from .util.vtkVariant import *

Source: https://github.com/Kitware/VTK/blob/v9.1.0/Wrapping/Python/vtkmodules/all.py.in

And trying to access the util object imported from all.py works:

$venv_dir/bin/python -c "import vtk; print('vtk imported'); print(vtk.vtkImageScalarTypeNameMacro); print(vtk.calldata_type); print(vtk.vtkVariantCreate)"
vtk imported
<function vtkImageScalarTypeNameMacro at 0x7f5f6eeedcb0>
<function calldata_type at 0x7f5f6eeffa70>
<function vtkVariantCreate at 0x7f5f5fe78200>
ebrahimebrahim commented 2 years ago

@jcfr Thank you for looking into this!

Acutally it seems that vtk.util is available in the application... but it's not sufficient to import vtk. One has to import vtk.util in order to use it.

Similarly I have to import vtk.util.numpy_support to use numpy support.

This actually makes it easy to close this issue, but it's still a mystery to me why import vtk is not sufficient in this custom app while it is sufficient in vanilla Slicer.

jcfr commented 2 years ago

Looking at some examples in VTK proper, it looks like directly importing works:

$venv_dir/bin/python -c "from vtk.util.numpy_support import get_vtk_array_type, get_numpy_array_type; print(get_vtk_array_type); print(get_numpy_array_type)"
<function get_vtk_array_type at 0x7ff5e31b6950>
<function get_numpy_array_type at 0x7ff5d05bd440>
ebrahimebrahim commented 2 years ago

Looking at some examples in VTK proper, it looks like directly importing works:

I see, thanks :grinning: I'll do that and close this issue then, thank you!

jcfr commented 2 years ago

but it's still a mystery

This is likely explained by some of the "magic" implemented in https://github.com/Kitware/VTK/blob/v9.1.0/Wrapping/Python/vtk.py

jcfr commented 2 years ago

All of that said, I suggest you look into the available methods allowing to create nodes directly from numpy array.

See https://slicer.readthedocs.io/en/latest/developer_guide/slicer.html#module-slicer.util

For example, the method slicer.util.updateSegmentBinaryLabelmapFromArray may be all you need.