Dear Slicer Developers,
I am trying to extend OpenIGTLinkIF module to transmit the tractography.
The tracts are vtkMRMLFiberBundleNode data, which is a derived class from vtkMRMLModelNode.
The OpenIGTLinkIF module is able to transmit vtkMRMLModelNode.
To make it work on vtkMRMLFiberBundleNode, i need to include the vtkMRMLFiberBundleNode.h file.
Unfortunately the vtkMRMLFiberBundleNode is defined in SlicerDMRI extension.
I could include the SlicerDMRI library, but then OpenIGTLinkIF module will depend on SlicerDMRI.
Do you think it might be possible to merge the mrmlNode define in the following link into Slicer trunk?
Thanks in advance!
IGTL converters for special nodes should be specified in the extension where those special nodes are defined (in SlicerDMRI).
For example, these design options could be used for handling vktMRMLFiberBundleNode conversion without introducing dependencies between extensions:
- Option A: Add a new OpenIGTLink device type (FIBERBUNDLE) which would encode its content the same way as a POLYDATA. You may even decide to only include those POLYDATA fields which make sense for fiber bundles.
- Option B: introducing a new “confidence” parameter in the IGTL converters. (similarly to file IO and DICOM plugins)
I will take a look into the IO and DICOM plugins for more information!
Fiber bundles are not really models. The design of using vtkMRMLModelNode as a base class of vtkMRMLFiberBundle node is not clean at all (requires many workarounds throughout Slicer code to make it work), but considering that it allowed relatively simple implementation, it somewhat makes sense.
However, it would be better if this questionable design choice would not be further propagated to OpenIGTLink as well. It would be much cleaner to have a new OpenIGTLink device (message) type for this distinct data type.
@ihnorton What do you think?
I don’t think depending on vtkMRMLFiberBundleNode.h would be very helpful. It should be sufficient to work with
vtkMRMLModelNode::GetPolyData output, but dispatch to custom encoding when
IsA("vtkMRMLFiberBundleNode"). The polydata will have all the points and cells to identify streamlines. If you need the secondary data (e.g. tensors or measurements along the tracts) those are stored as named arrays.
That said, I’m a bit curious what is the use-case; who needs this? There are already several other ways to get these nodes out to external software: CLIs, Steve’s MRML server setup, DICOM server (and probably others). Plain streamlines are pretty simple, but beyond that there’s a lot of complexity which has already been extensively considered in DICOM so I would suggest carefully considering whether it makes sense to recapitulate that specification.
I agree with your assessment of the design.
As far as OpenIGTLink, looking at the protocol, I think all the necessary data could be represented in the existing message types (POLYDATA for lines, NDARRAY for tensors and everything else). Whether it’s worth doing an ad-hoc naming scheme with existing message types or adding a tractography message type to the spec depends on the application and the desired direction of OpenIGTLink.
I totally agree that it really depends on the application and desired direction of OpenIGTLink.
The issue is the mismatch between the OpenIGTLink message type and the mrml node.
All mrmlNode can be represented in exsiting message types, but several different nodes could be represented in one message type(such as vtkMRMLFiberBundleNode and vtkMRMLModelNode are both represented in igtlPolyDataMessage type). Once the client receive the igtlPolyDataMessage, it needs additional steps to decide which node to choose to represent/visualize the data.
A tractography message derived from igtlPolyDataMessage could be a solution.
I will discuss with Junichi regarding this question.
Just to add: for receiving I think you can still avoid the dependency by using
vtkMRMLScene::CreateNodeByClass("vtkMRMLFiberBundleNode") to create the node if SlicerDMRI is installed, then
SetPolyData after deserialization.
(if SlicerDMRI is not installed then fall back to
vtkMRMLModelNode and likewise
SetPD – the streamlines should display fine as lines, but won’t have measurement-coloring or extended glyphing options provided by the FiberBundleDisplayNode* classes)
Right, that question is either a protocol change or application-specific interpretation of certain naming convention when deciding how to deserialize. (and FWIW, making that choice shouldn’t involve SlicerDMRI headers as far as I can understand)
Thanks a lot for your adding!
Hi Andras, Hi lsaiah,
Thanks for your kind suggestions,
I just make some commits in OpenIGTLinkIF module.
Once these commits are integrated, 3D slicer will be able to transmit fiberbundle data between machines