Developing a 3D Slicer extension
Links
- GUI
Debugging
TL;DR Pycharm Professional instructions work
- These instructions: SlicerRt/SlicerDebuggingTools: Extension for 3D Slicer containing various tools for module development and debugging1
- No need to change anything in module code
- During debugging everything freezes
- You can use pycharm python CLI to look around etc. — neat!
not TL;DR
- SlicerRt/SlicerDebuggingTools: Extension for 3D Slicer containing various tools for module development and debugging1
- needs pycharm Pro
- SlicerDebuggingTools/PyDevRemoteDebug/PyDevRemoteDebug.py at master · SlicerRt/SlicerDebuggingTools
- source of the 3dslicer bits
- pdb-attach · PyPI can attach to random programs,
os.getpid()
is my friend
- Documentation/4.5/Developers/FAQ/Python Scripting - Slicer Wiki at some point it was possible to use python-remote-pdb
- ionelmc/python-remote-pdb: Remote vanilla PDB (over TCP sockets). 2y ago last commit
- I can use these same instructions mostly for pdb-attach, I see no reason it shouldn’t work, python is python
- it Kiiiinda works but breaks after the first button
Giving up for now- Update: installed Pycharm Pro, works!
- Pycharm Pro egg was in
/opt/pycharm-professional/debug-eggs/pydevd-pycharm.egg
- Pycharm Pro egg was in
Basics
Starting Slicer
Loads the module automatically (for some reason doing it manually doesn’t preserve it across restarts?..)
Slicer --additional-module-path /path/to/my/extension/one/lower/than/what/i/would/pick/in/Slicer/GUI
Logging
- Not directly mentioned in the help because they state it’s always better to use the debugger2
- Slicer/Base/Python/slicer/slicerqt.py at main · Slicer/Slicer has the slicer setup
- I can do
logging.warning("test")
in the python console and it works - Slicer settings allow changing the loglevel of its python console!
Module types: CLI modules
Different types of modules exist: Module Overview — 3D Slicer documentation
In the first tests there was a lot of latency.
Solution: CLI modules (not extensions) that can run in the background and whose status can be queried, which can be added to new extension from extension editor.
Now I understad this better:
- CLI modules are simple I/O, non-blocking, that’s where the networkig logic should go to
- scripted are python scripts with GUIs
- This bit about running CLI in the backgroundPython FAQ — 3D Slicer documentation
Looking into the sample code
Module of type scripted
- Created an extension of type cmake, to which I added a module of type
scripted
. It’s the sample thresholding extension - Sample data
- It shows how to add sample data to the extension for testing
- It can then be found in the Sample Data module, named after the extension itself!
Module of type scriptedCLI
-
I hope it’s the same as type CLI, but only with python
-
Is a CLI script w/ an XML that has module metadata + examples
- CLI module goes in the same examles menu
- and a basic UI has been generated for it? Wow
- Running it from the UI actually shows a progress bar and it doesn’t block the interface! Woohoo!
-
Adding it added it to CMakeLists.xml:
add_subdirectory(my_scripted_cli)
-
python dev tools actually show the CLI used to run a CLI module!
- the input arguments are filepaths, and slicer automatically generates and then deletes temporary files for this when running
-
can’t debug it the usual way, I guess I’ll have to add the pydevd-pycharm things to the code
[VTK] /opt/3dslicer/bin/python-real /home/.../cli_model_service.py /tmp/Slicer-sh/IACHCI_vtkMRMLScalarVolumeNodeD.nrrd 1 /tmp/Slicer-sh/IACHCI_vtkMRMLScalarVolumeNodeF.nrrd
(Auto-creating) GUI
-
Slicer/Docs/developer_guide/parameter_nodes/gui_creation.md at main · Slicer/Slicer seems interesting
-
CLI modules have an interface specified by the .xml file, and the interface is generated based on it
couldn’t find any documentation onhow to write the XML: Documentation/Nightly/Developers/SlicerExecutionModel - Slicer Wiki
-
Bits about the XML
channel
is eitherinput
oroutput
, and only for pics.- No parameter names, just their
index
-
If I read the volume as volume, it uses the
.nrrd
file extension by default — and I want.nii
- Script repository deals with these settings, but I can’t use them from within a CLI module Script repository — 3D Slicer documentation
Auto-loading the module at startup
Module from console with arguments - Support - 3D Slicer Community
Slicer.exe --python-code "selectModule('SampleData'); getModuleGui('SampleData').setCategoryVisible('BuiltIn', False)"
File operations
Script repository — 3D Slicer documentation:
# Create a new directory where the scene will be saved into
import time
sceneSaveDirectory = slicer.app.temporaryPath + "/saved-scene-" + time.strftime("%Y%m%d-%H%M%S")
if not os.access(sceneSaveDirectory, os.F_OK):
os.makedirs(sceneSaveDirectory)
Inspiration
- User_Manual.md · develop · OpenDose / SlicerOpenDose3D · GitLab
- openDose3D is a cool example extension that shows many things
- SlicerTotalSegmentator/TotalSegmentator/TotalSegmentator.py at main · lassoan/SlicerTotalSegmentator
outputSegmentation.AddDefaultStorageNode() outputSegmentation.GetStorageNode().SetFileName(output_segmentation_path) outputSegmentation.GetStorageNode().ReadData(outputSegmentation)
Useful bits from documentation
- There’s a node type for tables
- statistics become a table
- also: many modules exist
- Documentation/Nightly/Extensions/MeshStatistics - Slicer Wiki / DCBIA-OrthoLab/MeshStatisticsExtension
- does a lot including creating a table GUI programmatically and CSV export etc.
- Documentation/Nightly/Extensions/MeshStatistics - Slicer Wiki / DCBIA-OrthoLab/MeshStatisticsExtension
- Colors: are not just colors, but class/label names as well