This notebook is shows how views and full application window can be displayed and configured to be used in JupyterLab when Slicer runs in a docker container or on a remote workstation.
It relies on a remote desktop connection and web proxy set up in the slicer-notebook docker image.
This notebook can be run in the web browser via Binder or locally using a Jupyter server started by this command:
docker run -p 8888:8888 -p49053:49053 -v path/to/my/notebooks:/home/sliceruser/work --rm -ti lassoan/slicer-notebook:latest
Notes:
path/to/my/notebooks
by the actual local path to your notebook folder.https://127.0.0.1:8888
page in your web browser and copy-paste the token from the docker container's output.# Read an image using SimpleITK
import JupyterNotebooksLib as slicernb
import slicer
import SimpleITK as sitk
import sitkUtils as su
# Load 3D image using SimpleITK
reader = sitk.ImageFileReader()
reader.SetFileName("data/MRBrainTumor1.nrrd")
image = reader.Execute()
# Get the SimpleITK image into the Slicer scene
slicer.mrmlScene.Clear(False) # clear any previously loaded data from the scene
volumeNode = su.PushVolumeToSlicer(image)
# Show volume in slice views
slicernb.ViewDisplay("FourUp") # choose a layout where 3 slice views are present
slicer.util.setSliceViewerLayers(background=volumeNode, fit=True) # show this volume in slice viewers
# Create slice view widgets in the notebook
from ipywidgets import VBox
viewWidgets = VBox([slicernb.ViewSliceWidget('Red'), slicernb.ViewSliceWidget('Yellow'), slicernb.ViewSliceWidget('Green')])
viewWidgets.layout.max_width="400px"
display(viewWidgets)
VBox(children=(ViewSliceWidget(children=(FloatSlider(value=0.0, description='Offset', max=78.40000000000003, m…
# Apply some processing and view the udpated results
# Process image
blurFilter = sitk.SmoothingRecursiveGaussianImageFilter()
blurFilter.SetSigma(1.0)
blurredImage = blurFilter.Execute(image)
# Update view widgets (without this, the user would need to move the sliders to get an updated image)
su.PushVolumeToSlicer(blurredImage, targetNode=volumeNode)
for viewWidget in viewWidgets.children:
viewWidget.sliceView.updateImage()
# Set up application window
app = slicernb.AppWindow()
# Hide patient information from slice view
slicernb.showSliceViewAnnotations(False)
# Show markups toolbar
slicer.modules.markups.toolBarVisible=True
# Show volume in 3D view using volume rendering
slicernb.showVolumeRendering(volumeNode, True)
display(app)
Before executing the next cell, add markups to the scene: click on the toolbar buttons to create markups, then click in the viewers to place them.
If no markups are added then the output of the next cell will be empty.
# Display control point positions in each markup node.
from IPython.display import HTML
for markupsNode in slicer.util.getNodesByClass("vtkMRMLMarkupsNode"):
display(HTML(f"<h3>Markup: {markupsNode.GetName()}</h3>"))
display(slicernb.displayable(markupsNode))
label | position.R | position.A | position.S | selected | visible | description | |
---|---|---|---|---|---|---|---|
0 | OC-1 | 56.622961 | -12.807881 | 0.7 | True | True | |
1 | OC-2 | -22.919169 | -16.178310 | 0.7 | True | True | |
2 | OC-3 | -22.919169 | -16.178310 | 0.7 | True | True | |
3 | OC-4 | -34.378628 | 56.622961 | 0.7 | True | True |
label | position.R | position.A | position.S | selected | visible | description | |
---|---|---|---|---|---|---|---|
0 | A-1 | 30.814281 | 0.4685 | 40.719202 | True | True | |
1 | A-2 | 57.226737 | 0.4685 | 19.149030 | True | True | |
2 | A-3 | 44.020509 | 0.4685 | 11.225294 | True | True |
label | position.R | position.A | position.S | selected | visible | description | |
---|---|---|---|---|---|---|---|
0 | F-1 | -0.469 | 84.299504 | 27.072767 | True | True | |
1 | F-2 | -0.469 | -30.594678 | 9.024256 | True | True | |
2 | F-3 | -0.469 | 36.757084 | -7.263425 | True | True | |
3 | F-4 | -0.469 | 27.072517 | 30.594428 | True | True | |
4 | F-5 | -0.469 | -14.747204 | -45.121278 | True | True | |
5 | F-6 | -0.469 | -45.121528 | -48.642939 | True | True | |
6 | F-7 | -0.469 | -64.050455 | -24.431521 | True | True | |
7 | F-8 | -0.469 | 1.540477 | 52.164600 | True | True | |
8 | F-9 | -0.469 | 85.620127 | -36.757334 | True | True | |
9 | F-10 | -0.469 | 36.316876 | -40.278995 | True | True |
markupsNode = slicer.util.getNodesByClass("vtkMRMLMarkupsNode")[0]
markupsNode.GetName()
'OC'
# Show full markups module GUI
app.setContents("viewers")
slicer.util.findChild(slicer.util.mainWindow(), "PanelDockWidget").show()
slicer.modules.markups.toolBarVisible=True
slicer.util.selectModule("Markups")
# Show full application GUI
app.setContents("full")
# Create link that shows the application GUI in a new browser tab
from ipywidgets import HTML
HTML(f"""<a href="{slicernb.AppWindow.defaultDesktopUrl()}" target="_blank">
<b>Click here</b> to open application window in a new browser tab.</a>""")
HTML(value='<a href="/desktop/" target="_blank">\n<b>Click here</b> to open application window in a new browse…
# Show only viewers
app.setContents("viewers")
from ipywidgets import Button, HBox
import JupyterNotebooksLib as slicernb
fullButton = Button(description='Full')
fullButton.on_click(lambda b: slicernb.AppWindow().setContents("full"))
viewersButton = Button(description='Viewers')
viewersButton.on_click(lambda b: slicernb.AppWindow().setContents("viewers"))
markupsToolbarToggleButton = Button(description='Markups toolbar')
def toggleMarkupsToolBar(b):
slicer.modules.markups.toolBarVisible = not slicer.modules.markups.toolBarVisible
markupsToolbarToggleButton.on_click(toggleMarkupsToolBar)
HBox([fullButton, viewersButton, markupsToolbarToggleButton])
HBox(children=(Button(description='Full', style=ButtonStyle()), Button(description='Viewers', style=ButtonStyl…