BICCN / cell-locator

manually align specimens to annotated 3D spaces
https://cell-locator.readthedocs.io
Other
19 stars 7 forks source link

Python Annotation Export CLI Tool #215

Closed allemangD closed 1 year ago

allemangD commented 2 years ago

Creating a draft PR to discuss the CLI tool for exporting annotation JSON as model or volume.

There is some difficulty dealing with the various coordinate systems involved. In general, I think the output model/volume should be in the same coordinate system and resolution as the input atlas; however detecting the input coordinate system (RAS, IPS, etc.) I don't think is possible without adding some flag arguments.

For now I only support the coordinates used already used in Cell Locator, so the tool is compatible with those atlas and annotation files.

The output model is the same model displayed in the Cell Locator 3D view, and the output volume is a labelmap with value 1 inside the annotation and value 0 outside.

From Scripts/cltool/README.md:

Usage

Launch with: slicer --no-main-window --python-script main.py <atlas> <annotation> <model> <volume>

Arguments:
  <atlas volume>  (.nrrd atlas volume or label map)
  <annotation>    (.json cell locator annotations)
  <output model>  (.vtk output path for model)
  <output volume> (.nii[.gz] output path for labelmap)

Future work

Include CLI flags to enable coordinate conversions, so that the new atlas files will work with this tool.

Support multiple annotations within a single annotation.json. Add options to export each annotation in a separate model/volume, or to output the union of all contained models.

Correctly support different annotation types (spline/polyline/point) and annotation thicknesses. Currently only spline is supported.

Correctly support nrrd/nifti input/output volumes. SlicerIO package will assist in this.

allemangD commented 2 years ago

Updated the PR description with recent changes. I have space transforms working correctly between all of RAS, LPS, and PIR coordinate systems.

The usage I intend is to add 3 optional CLI arguments:

--atlas-space pir
--annotation-space ras
--target-space <atlas-space>

The default behavior would then be:

allemangD commented 2 years ago

@lydiang Spline/polyline annotation types are respected starting in 894df4d. Let me know if you have issues getting the script up and running.

allemangD commented 2 years ago

@lydiang The tool does not correctly handle the coordinate space of the human atlas. I am still investigating, but somehow the position is incorrectly copied to the output volume. I'll provide an update commit and exmaple CLI arguments once I get this resolved.

allemangD commented 2 years ago

The issue arises from vtk python's limited ability to parse the NRRD headers (and missing ability to write NRRD files). These functionalities are currently provided by slicer; we can address porting these functionalities alongside the vtkCurveGenerator.

To mitigate this for now, I am restricting the tool to only read/write nifti files. vtk python has built-in ability to parse the nifti header and extract the transformation of the atlas.

I will soon push a commit modifying the tool to enforce nifti files, along with some sample usage scripts and a script to convert nrrd to nifti.

allemangD commented 2 years ago

These functionalities are currently provided by slicer; we can address porting these functionalities alongside the vtkCurveGenerator

Since this is core functionality missing from VTK it makes more sense to merge the Slicer implementation upstream to VTK, rather than vtkAddon. The Slicer implementation uses the third-party teem library: https://github.com/Slicer/Slicer/tree/main/Libs/vtkTeem

See discussion at https://gitlab.kitware.com/vtk/vtk/-/merge_requests/5656#note_1216089

allemangD commented 2 years ago

@lydiang After f6ee683 and 521d903, you can load atlases in .nii.gz format, and specify spaces via CLI flags.

The default behavior is now to assume all coordinates are in the same space. CCF annotations should use --atl pir to specify the atlas space. The annotation models are then converted to that space.

Human annotations shouldn't need any space arguments.

Do note that the output volume's origin is not correctly copied from the atlas volume, so the output labelmap may not be correct. I'm investigating the issue. The model is exported correctly.

jcfr commented 2 years ago

re: reading nrrd/nii files

@allemangD To follow up on our discussion, the itk wheel could be used to read in the data and then the function itk.vtk_image_from_image could be used to get a vtkImageData with metadata set (direction, origin, ...)

Thanks @thewtex for the suggestion

allemangD commented 1 year ago

Made some significant progress; the tool is stable enough now that I've squashed all those WIP commits together.

Do note that I'm now importing vtkAddon for vtkCurveGenerator. Running the script now requires a local build of both vtkAddon and VTK, pending a working PyPI package that can link against the VTK already on PyPI. It no longer requires being launched through Slicer, so long as the VTK/vtkAddon libraries are on the PYTHONPATH.

See the README.md or main.py docstring for some basic commands to build VTK/vtkAddon and some sample usage of the script. https://github.com/BICCN/cell-locator/tree/python-volume-export/Scripts/cltool

Each annotation is still output to the same VTK model file, but they have different IDs in the output labelmap.

3D view of labelmap volume rendering

2D view of labelmap

The vtkAddon changes are introduced in https://github.com/Slicer/vtkAddon/pull/31

allemangD commented 1 year ago

:rocket: :tada:

I've built and published v0.0.1 of the CLI tool to PyPI. https://pypi.org/project/cell-locator-cli/

I've tested pip install cell-locator-cli, cl-convert, cl-export on Linux and Windows.


I've set up GitHub Actions for build/deployment to PyPI, but I don't have permissions to add a PyPI token to this repo's secrets. I built/uploaded v0.0.1 manually but have tested the workflow in a separate repository. Whenever a tag of the form cli-vX.Y.Z is pushed, actions will publish that version to PyPI. See https://github.com/BICCN/cell-locator/tree/cli-v0.0.1

Secret PYPI_API_TOKEN needs to hold a token with access to project cell-locator-cli.

I suggest to create a new release/tag cli-v0.1.0 once that token is added and this PR merged.


I've added basic docs and there is --help text for both cl-convert and cl-export. Pending review I will merge this PR and begin refining user documentation.

allemangD commented 1 year ago

Rebased on master to resolve conflicts. Merging now.

allemangD commented 1 year ago

GitHub Actions was successful!

https://github.com/BICCN/cell-locator/actions/runs/3516630446 https://github.com/BICCN/cell-locator/releases/tag/cli-v0.1.0 https://pypi.org/project/cell-locator-cli/0.1.0/