Skip to content

Python interactor

Davide Punzo edited this page Sep 20, 2017 · 41 revisions

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:

Install Additional Python packages

3DSlicer and SlicerAstro binaries deliver its own Python environment. The Python version is 2.7 and it incorporates the additional package numpy. It is possible to install additional 'pure' python packages from the Python interactor as follow:

import pip 
pip.main(['install', 'astropy'])

3DSlicer Python scripts repository

SlicerAstro Python scripts repository

  • 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 array(pattern = "", index = 0):
      """Return the array you are "most likely to want" from the indexth
      MRML node that matches the pattern.  Meant to be used in the python
      console for quick debugging/testing.
      """
    
      import vtk.util.numpy_support
      n = getNode(pattern=pattern, index=index)
      i = n.GetImageData()
      shape = list(n.GetImageData().GetDimensions())
      shape.reverse()
      a = vtk.util.numpy_support.vtk_to_numpy(i.GetPointData().GetScalars()).reshape(shape)
      return a
    
    
  • 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()
    
    
  • more to come...

Clone this wiki locally