Python script : Time series of 4D volume & loading synchronized nodes

Hello,

I’m playing with 4D data format and Slicer. I found lots of information on the forum but I’m looking for additional details.

The final objective.

To load multiple 4D nifti volume (3D+time) in the sequence module and synchronise them to plot for instance the 1D profil of all datasets together. Such routine have to be done with the python script.

The current workflow.

a) conversion of the 4D nifti in nrrd file that is the format dedicated to handle 4D data in slicer. I used the multivolume importer. [OK]
b) save the data as an nrrd. [OK] Reloading the nrrd file and plotting them work using the multivolume explorer [OK]
c) Load the nrrd file as a sequence node, as suggested here [OK] link
d) load the nrrd file as synchronized node in the sequence module ?

The questions

In a) I have a warning message for

    Warning: /home/vozenne/Test_D_0.5_Q_0.75.nii.gz does not have TimeSeries intent, instead it has "Nothing"
Trying to read as TimeSeries anyway

That’s expected becasue the nifti format only specify the “spacing” of each direction. The 4th dimension being the time but to my knowledge, there is no specific time header per image in nifti.

  • Q1: Is it possible to fill the TimeSeries information inside slicer ?
  • Q2: Is it possible to change the name of the node, or to change the name of sequence node using python ?

Q3 While step a), b) and c) is working , the code create two sequences (this is normal) but I wish to have one sequence with synchronized nodes, do you have any example in python for such feature ?

Thanks in advance
Best
Valéry

I put the code below

import numpy as np
import os 

import MultiVolumeImporter

importer = MultiVolumeImporter.MultiVolumeImporterWidget()

mvNode1 = slicer.mrmlScene.CreateNodeByClass('vtkMRMLMultiVolumeNode')
slicer.mrmlScene.AddNode(mvNode1)
niiFilePath ="/home/vozenne/Test_D_0.5_Q_0.5.nii.gz"
importer.read4DNIfTI(mvNode1, niiFilePath)
slicer.util.saveNode(mvNode1 , "/home/vozenne/Test_D_0.5_Q_0.5.nrrd")


mvNode2 = slicer.mrmlScene.CreateNodeByClass('vtkMRMLMultiVolumeNode')
slicer.mrmlScene.AddNode(mvNode2)
niiFilePath ="/home/vozenne/Test_D_1_Q_1.nii.gz"
importer.read4DNIfTI(mvNode2, niiFilePath)
slicer.util.saveNode(mvNode2 , "/home/vozenne/Test_D_1_Q_1.nrrd")

# see https://discourse.slicer.org/t/loading-4d-volume-as-sequence-using-python-script/13076/4
sequenceNode1 = slicer.util.loadNodeFromFile("/home/vozenne/Test_D_0.5_Q_0.5.nrrd", "SequenceFile")
sequenceNode2 = slicer.util.loadNodeFromFile("/home/vozenne/Test_D_1_Q_1.nrrd", "SequenceFile")
#exit()

MultiVolume is limited to working with volumes only and can do synchronize browsing of only two volumes at a time. Sequences module does not have any of these limitations, can work with any node types (models, transforms, markups, etc) and can do synchronized browsing of any number of nodes. Due to these reasons, MultiVolume modules will be deprecated soon (there are just a few minor features that need to be made available for sequences). So, I would recommend to use Sequences instead of MultiVolume. If you save a multivolume node then you can load is a volume sequence if you choose that in the Description column in “Add data” dialog (or you can make Slicer automatically load a nrrd file as a volume sequence if the file extension is .seq.nrrd).

Nifti file format has many issues and limitations, so we have been trying to convince people to use nrrd instead (unless they actually use nifti what it is developed for - brain imaging). Why would you like to use nifti instead of nrrd?

For plotting time plots for many volumes, you need to write a small Python script, as MultiVolume supports plotting two, and Sequences module supports plotting only one.

Thanks a lot for the quick answer. I should explain better my issue and also answer the following question:

“Why would you like to use nifti instead of nrrd?”

Yes , this is not ideal. But the data are currently generated in NIFTI and I did know that this is not Slicer compatible for 3D+t so I convert them in nrrd. This easiest way I found to convert them in nrrd was to load them using Slicer using the multivolume importer and to save them. I wish I will remove this step in the future and not use anymore the MultiVolumeImporter.

But let’s forget this part I should have focus my questions.

Description of my issue

Here is the new description of my issue (My terminology is maybe/surely wrong, I apologized for my bad understanding of the sequence module. )

sequenceNode1 = slicer.util.loadNodeFromFile("/home/vozenne/A.nrrd", "SequenceFile")
sequenceNode2 = slicer.util.loadNodeFromFile("/home/vozenne/B.nrrd", "SequenceFile")
  • Using the two previous lines of code, I can load the two .nrrd files as sequence and play them. This is perfectly working.
  • The code below create 2 sequences browser (named A_browser & B_browser) with one sequence (or node ?) for each (A & B respectively) .
  • In the interface , under the panel synchronized nodes, using the [+] button I can add the sequence B to the sequence browser A_browser. Then A and B seems synchronized.

But I didn’t find how to perform the final step in python.

Questions

  • Do you have any link to an example, or similar example ?
  • I wish learn more in detail how to use the sequence module, what/where would be the best doc/code to learn about the sequence module and the terminology ( sequence browser, sequence, and proxy )?

Plotting

“For plotting time plots for many volumes”
I’m effectively planning to write a small Python script, I wish to use the sequence module and find a way to plot synchronized nodes together. Maybe in a none interactive fashion using numpy at first ?

Is there an equivalent of slicer.util.arrayFromVolume for the sequence module? For instance, does a sequence with can be considered as a standard object in slicer. By the past, I succeed to write some python scripts for plotting images , making figures on multiple datasets and typical overlay with presonnalized display configuration (with displayNode option for instance). For doing such scripts, I mostly copy and paste code from the forum, example and documentation, it was perfect but now I’m a bit lost the sequence module in particular for loading and manipulating the data.

Thanks a lot in advance for your help,

I would recommend to load the sequences with automatic showing disabled (to prevent creating browser nodes), and then create one browser node and add all the sequences:

sequenceFiles = ["/home/vozenne/A.nrrd", , "/home/vozenne/B.nrrd"]
browserNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSequenceBrowserNode")
for sequenceFile in sequenceFiles:
  sequenceNode = slicer.util.loadNodeFromFile(sequenceFile, "SequenceFile", {"show": False})
  browserNode.AddSynchronizedSequenceNode(sequenceNode)

# Show sequence browser toolbar
slicer.modules.sequences.showSequenceBrowser(browserNode)

See this example in the script repository.

Thanks so much, it is working perfectly.
The section Sentences mentioned in the example was unknown to me, sorry.
I might have other questions regarding the plotting in the close future .
Best
Valéry

1 Like