-
Notifications
You must be signed in to change notification settings - Fork 7
Python interactor
The Python interactor is a very useful util to access run-time any 3DSlicer and SlicerAstro classes: MRML nodes, Widgets and Logics (e.g., the data of the fits file are stored in the MRML AstroVolume class). Python script can also be runned by typing on the terminal:
Slicer --python-script example.py
or by copying and pasting the code in the python console of 3DSlicer:

See also:
- https://www.slicer.org/slicerWiki/index.php/Documentation/Nightly/Developers/Python_scripting
- http://www.slicer.org/slicerWiki/images/d/d7/Slicer4_ProgrammingTutorial_SPujol-SPieper_slicer4.4.pdf
3DSlicer and SlicerAstro binaries deliver its own Python environment. The Python version is 2.7.13 and it incorporates the additional packages numpy, astropy, scipy. It is possible to install additional 'pure' python packages from the Python interactor as follow:
import pip
pip.main(['install', 'package_name'])-
SmoothRenderSaveVideos.py:
slicer.util.loadVolume("/full_path/galaxy.fits",{"center":True}) mw = slicer.util.mainWindow() ms = mw.moduleSelector() # Smooth the datacube ms.selectModule('AstroSmoothing') smowidget = slicer.modules.astrosmoothing.widgetRepresentation() smomrmlpara = smowidget.mrmlAstroSmoothingParametersNode() smomrmlpara.SetMode("Manual") # only if a GPU is present: #smomrmlpara.SetHardware(1) smowidget.onApply() ms.selectModule('AstroVolume') # Setting maximum quality for the rendering astrovolumewidget = slicer.modules.astrovolume.widgetRepresentation() astrovolumewidget.onCurrentQualityControlChanged(1) volumes = slicer.mrmlScene.GetNodesByClass("vtkMRMLAstroVolumeNode") volumefiltered = volumes.GetItemAsObject(1) smomrmlpara.SetInputVolumeNodeID(volumefiltered.GetID()) astrovolumewidget.onCurrentQualityControlChanged(1) # Create videos ms.selectModule('ScreenCapture') screencapturewidget = slicer.modules.screencapture.widgetRepresentation() instance = screencapturewidget.self() viewNode = slicer.util.getNode('vtkMRMLViewNode1') instance.viewNodeSelector.setCurrentNode(viewNode) instance.numberOfStepsSliderWidget.setValue(360) instance.videoExportCheckBox.setChecked(1) instance.videoFormatWidget.setCurrentIndex(1) instance.videoFileNameWidget.setText("WEIN069.mp4") instance.videoLengthSliderWidget.setValue(6) instance.onCaptureButton() viewNode = slicer.util.getNode('vtkMRMLViewNode2') instance.viewNodeSelector.setCurrentNode(viewNode) instance.viewNodeSelector.setCurrentNode(viewNode) instance.numberOfStepsSliderWidget.setValue(360) instance.videoExportCheckBox.setChecked(1) instance.videoFormatWidget.setCurrentIndex(1) instance.videoFileNameWidget.setText("WEIN069_smoothed.mp4") instance.videoLengthSliderWidget.setValue(6) instance.onCaptureButton()
-
Create(alike)MomentMap.py:
# Get the data-cube volume volumeNode = getNode('name of the object') datacube = volumeNode.GetImageData() # Get dimensions N1 = int(volumeNode.GetAttribute("SlicerAstro.NAXIS1")) N2 = int(volumeNode.GetAttribute("SlicerAstro.NAXIS2")) RMS = float(volumeNode.GetAttribute("SlicerAstro.RMS")) # Create an empty 2-D image imageSize = [N1, N2, 1] imageSpacing = [1.0, 1.0, 1.0] voxelType = vtk.VTK_FLOAT imageDataTemp = vtk.vtkImageData() imageDataTemp.SetDimensions(imageSize) imageDataTemp.SetSpacing(imageSpacing) imageDataTemp.AllocateScalars(voxelType, 1) extentTemp = imageDataTemp.GetExtent() for i in xrange(extentTemp[0], extentTemp[1]+1): for j in xrange(extentTemp[2], extentTemp[3]+1): for k in xrange(extentTemp[4], extentTemp[5]+1): imageDataTemp.SetScalarComponentFromFloat(i,j,k,0,0.) # calculate moment map imageData = volumeNode.GetImageData() extent = imageData.GetExtent() for i in xrange(extent[0], extent[1]+1): for j in xrange(extent[2], extent[3]+1): sum = 0. for k in xrange(extent[4], extent[5]+1): value = imageData.GetScalarComponentAsFloat(i,j,k,0) if value > 3 * RMS: sum += value imageDataTemp.SetScalarComponentFromFloat(i,j,0,0,sum) imageDataTemp.Modified() point = imageDataTemp.GetPointData() array = point.GetArray("ImageScalars") point.Modified() array.Modified() array.GetValueRange() # create Astro Volume for the moment map astroVolumeLogic = slicer.modules.astrovolume.logic() volumeNodeMomentMap = astroVolumeLogic.CloneVolume(slicer.mrmlScene, volumeNode, 'MomentMap') # modify fits attributes volumeNodeMomentMap.SetAttribute("SlicerAstro.NAXIS", "2") volumeNodeMomentMap.RemoveAttribute("SlicerAstro.NAXIS3") volumeNodeMomentMap.RemoveAttribute("SlicerAstro.CROTA3") volumeNodeMomentMap.RemoveAttribute("SlicerAstro.CRPIX3") volumeNodeMomentMap.RemoveAttribute("SlicerAstro.CRVAL3") volumeNodeMomentMap.RemoveAttribute("SlicerAstro.CTYPE3") volumeNodeMomentMap.RemoveAttribute("SlicerAstro.CUNIT3") volumeNodeMomentMap.RemoveAttribute("SlicerAstro.DTYPE3") volumeNodeMomentMap.RemoveAttribute("SlicerAstro.DRVAL3") volumeNodeMomentMap.RemoveAttribute("SlicerAstro.DUNIT3") # copy 2-D image into the Astro Volume object volumeNodeMomentMap.SetAndObserveImageData(imageDataTemp) volumeNodeMomentMap.UpdateNoiseAttributes() volumeNodeMomentMap.UpdateRangeAttributes() # change colorMap of the 2-D image displayNode = volumeNodeMomentMap.GetDisplayNode() displayNode.SetAndObserveColorNodeID('vtkMRMLColorTableNodeRainbow') # changing the colorMap parameters #displayNode.AutoWindowLevelOff() #displayNode.SetWindow(??) #displayNode.SetLevel(??) -
AccessDataAsNumpy.py:
def astroArrayFromVolume(volumeNode):
"""Return voxel array from volume node as numpy array.
Voxels values are not copied. Voxel values in the volume node can be modified
by changing values in the numpy array.
After all modifications has been completed, call volumeNode.Modified().
.. warning:: Memory area of the returned array is managed by VTK, therefore
values in the array may be changed, but the array must not be reallocated
(change array size, shallow-copy content from other array most likely causes
application crash). To allow arbitrary numpy operations on a volume array:
1. Make a deep-copy of the returned VTK-managed array using :func:`numpy.copy`.
2. Perform any computations using the copied array.
3. Write results back to the image data using :py:meth:`updateVolumeFromArray`.
"""
scalarTypes = ['vtkMRMLAstroVolumeNode', 'vtkMRMLAstroLabelMapVolumeNode']
vimage = volumeNode.GetImageData()
nshape = tuple(reversed(volumeNode.GetImageData().GetDimensions()))
narray = None
if volumeNode.GetClassName() in scalarTypes:
narray = vtk.util.numpy_support.vtk_to_numpy(vimage.GetPointData().GetScalars()).reshape(nshape)
return narray
def astroUpdateVolumeFromArray(volumeNode, narray):
"""Sets voxels of a volume node from a numpy array.
Voxels values are deep-copied, therefore if the numpy array
is modified after calling this method, voxel values in the volume node will not change.
Dimensions and data size of the source numpy array does not have to match the current
content of the volume node.
"""
vshape = tuple(reversed(narray.shape))
if len(vshape) == 1:
narray = numpy.expand_dims(narray, axis=0)
narray = numpy.expand_dims(narray, axis=0)
vshape = tuple(reversed(narray.shape))
vcomponents = 1
elif len(vshape) == 2:
narray = numpy.expand_dims(narray, axis=0)
vshape = tuple(reversed(narray.shape))
vcomponents = 1
elif len(vshape) == 3:
vcomponents = 1
else:
raise RuntimeError("Unsupported numpy array shape: "+str(narray.shape))
vimage = volumeNode.GetImageData()
if vimage is None:
vimage = vtk.vtkImageData()
volumeNode.SetAndObserveImageData(vimage)
vtype = vtk.util.numpy_support.get_vtk_array_type(narray.dtype)
vimage.SetDimensions(vshape)
vimage.AllocateScalars(vtype, vcomponents)
narrayTarget = astroArrayFromVolume(volumeNode)
narrayTarget[:] = narray
# Notify the application that image data is changed
# (same notifications as in vtkMRMLVolumeNode.SetImageDataConnection)
imageData = volumeNode.GetImageData()
pointData = imageData.GetPointData() if imageData else None
if pointData is not None:
if pointData.GetScalars() is not None:
pointData.GetScalars().Modified()
volumeNode.StorableModified()
volumeNode.Modified()
volumeNode.InvokeEvent(slicer.vtkMRMLVolumeNode.ImageDataModifiedEvent, volumeNode)
-
maskVolumeWithLabelVolume.py:
# Get the data-cube volumes volumeNode = getNode('Name') volumeLabelNode = getNode('LabelName') # masking imageData = volumeNode.GetImageData() imageDataLabel = volumeLabelNode.GetImageData() extent = imageData.GetExtent() for i in xrange(extent[0], extent[1]+1): for j in xrange(extent[2], extent[3]+1): for k in xrange(extent[4], extent[5]+1): if imageDataLabel.GetScalarComponentAsFloat(i,j,k,0) < 1 : imageData.SetScalarComponentFromFloat(i,j,k,0, 0.) # update volume keywords volumeNode.UpdateNoiseAttributes() volumeNode.UpdateRangeAttributes() -
accessSlicerAstrovtkFits.py:
import vtkFitsPython as vtkFits vtkFits.vtkFITSReader() dir(vtkFits) -
more to come...
Quick Links: Home • Download • SlicerAstro Roadmap • Tutorial • 3DSlicer User Manual • SlicerAstro User Manual • Python Interactor • Developer Manual
![]()