Resample Scalar Volumes - Scripting in Python

Hello,

I am trying to generate transformations and resample scalar volumes in Slicer programmatically with Python. And have two questions:

  1. I am unable to find a scripted module corresponding to ‘Resample Scalar/Vector/DWI Volume’ on GitHub. The steps I need to implement are - set input volume, create new output volume as, set the transform, reference volume, and ensure linear interpolation. Can someone please help me to get started?
  2. I am working in a Jupyter Notebook with Slicer kernel. As an attempt at automation, I am trying to pause my run, prompt user to add fiducials to the image on Slicer, and then continue running the script.
    This is not working as it just freezes my jupyter notebook and fails the kernel. Any suggestions on how I could implement this?

Thank you,
Sharada

It is implemented in C++, see source code here. You can call CLI module from Python as described here.

Notebooks are great for development and batch processing but if you want to implement interactive workflows for end users then scripted modules is a much more suitable option. You can create a simple GUI that contains a node selector to place markups points, maybe some more GUI widgets to set parameters, etc. Script in your notebook will become the module logic. I would recommend the PerkLab bootcamp Slicer programming tutorial to learn how to turn your script into a Slicer module.

Hi Andras,

Thank you for the quick response! I tried following the example you provided for the 1st problem and I still have an error. I have an input volume labeled ‘Axial’ and a transform ‘ACPC Transform’ already created in Slicer.

I don’t understand why there is no data assigned to “Input Volume” when I clearly have.

I tried looking for similar issues and could not troubleshoot. I might be missing something very minor as I am new to Slicer. Could you please help?

I will follow your advice about my 2nd question - thanks for the input on that.

Thanks,
Sharada

Probably you should do something like

firstVolumeNode = slicer.mrmlScene.GetFirstNodeByClass("vtkMRMLScalarVolumeNode")
...
parameters["inputVolume"] = firstVolumeNode
...

Plus: you need to 100 % sure about each parameter name. At least “Reference Volume (xxxx)” from your example seems not correct.

Just checked the source of resampleModule (link above) and it shows that the CLI call needs the following parameter strings: “inputVolume”, “outputVolume”, “referenceVolume”, “transformationFile” and “interpolationType” .

Thank you, yes. I also found the same thing after your comment about verifying the parameter names. Unfortunately, I have the same error still. I tried pulling the volumes using “slicer.mrmlScene.GetFirstNodeByClass” like you mentioned, instead of “slicer.util.getNode” just to see if it would make a difference. I still have the same error.

I am not familiar with C++, so it is a little hard for me to understand the logic. Any other suggestions?

Thanks,
Sharada

Here is a complete description of all the parameters.

“inputVolume” (a pathlike object or string representing an existing file) – Input Volume to be resampled.

As the error message tells, you provided a collection of nodes, instead of a volume node. This is because the method you used provides a collection of nodes. I would recommend to use slicer.util helper functions to get nodes from the scene because they are easier to use in Python.

Thank you so much Rudolf and Andras! I was able to follow your advice and pass the right datatype. I visualized the volume resampled manually using Slicer and the one I did with Python - They match perfectly.



My 3D rendering is not working for some reason, but I think this definitely solved my issue.

Thanks again for the wonderful software and all the support you provide!

Best,
Sharada

1 Like

Quick update - ‘slicer.util.getNode’ works too! The parameter names were the only thing that changed between what you see below and what I had before.

outputVolumeNode = slicer.mrmlScene.AddNewNodeByClass(“vtkMRMLScalarVolumeNode”)
outputVolumeNode.SetName(‘Axial ACPC’)

resampleModule = slicer.modules.resamplescalarvectordwivolume

parameters = {}
parameters[‘inputVolume’] = slicer.util.getNode(‘Axial’)
parameters[‘outputVolume’] = slicer.util.getNode(‘Axial ACPC’)
parameters[‘referenceVolume’] = slicer.util.getNode(‘Axial’)
parameters[‘transformationFile’] = slicer.util.getNode(‘ACPC_Transform’)
parameters[‘interpolationType’] = ‘linear’

cliNode = slicer.cli.runSync(resampleModule,None,parameters)

if cliNode.GetStatus() & cliNode.ErrorsMask:
errorText = cliNode.GetErrorText()
slicer.mrmlScene.RemoveNode(cliNode)
raise ValueError("CLI execution failed: " + errorText)

2 Likes