Example #1
0
    def onInputChanged(self):
        self.__chartTable.SetNumberOfRows(self.numFrames)

        self.plotFrame.enabled = True
        # self.plotFrame.collapsed = 0
        self.__xArray.SetNumberOfTuples(self.numFrames)
        self.__xArray.SetNumberOfComponents(1)
        self.__xArray.Allocate(self.numFrames)
        self.__xArray.SetName('frame')
        self.__yArray.SetNumberOfTuples(self.numFrames)
        self.__yArray.SetNumberOfComponents(1)
        self.__yArray.Allocate(self.numFrames)
        self.__yArray.SetName('signal intensity')

        self.__chartTable = vtk.vtkTable()
        self.__chartTable.AddColumn(self.__xArray)
        self.__chartTable.AddColumn(self.__yArray)
        self.__chartTable.SetNumberOfRows(self.numFrames)

        # get the range of intensities for the
        self.__mvRange = [0, 0]
        for v in self.nodeImgList[0][0]:
            frame = v
            frameRange = frame.GetScalarRange()
            self.__mvRange[0] = min(self.__mvRange[0], frameRange[0])
            self.__mvRange[1] = max(self.__mvRange[1], frameRange[1])

        # self.__mvLabels = string.split(self.__mvNode.GetAttribute('MultiVolume.FrameLabels'),',')
        #if len(self.__mvLabels) != nFrames:
        #  return
        self.__mvLabels = []
        for l in range(self.numFrames):
            self.__mvLabels.append(float(l))
Example #2
0
  def updateChart(self):
    outputTransformSequenceNode = self.outputTransformSequenceSelector.currentNode()
    
    self.__chart.RemovePlot(0)

    if outputTransformSequenceNode == None:
      return
      
    if outputTransformSequenceNode.GetDataNodeClassName() != "vtkMRMLLinearTransformNode":
      return
      
    numOfDataNodes = outputTransformSequenceNode.GetNumberOfDataNodes()
    indexName = outputTransformSequenceNode.GetIndexName()
    self.__xArray.SetNumberOfTuples(numOfDataNodes)
    self.__xArray.SetNumberOfComponents(1)
    self.__xArray.Allocate(numOfDataNodes)
    self.__xArray.SetName(indexName)
    
    self.__yArray.SetNumberOfTuples(numOfDataNodes)
    self.__yArray.SetNumberOfComponents(1)
    self.__yArray.Allocate(numOfDataNodes)
    self.__yArray.SetName('DisplacementX')

    self.__zArray.SetNumberOfTuples(numOfDataNodes)
    self.__zArray.SetNumberOfComponents(1)
    self.__zArray.Allocate(numOfDataNodes)
    self.__zArray.SetName('DisplacementY')

    self.__mArray.SetNumberOfTuples(numOfDataNodes)
    self.__mArray.SetNumberOfComponents(1)
    self.__mArray.Allocate(numOfDataNodes)
    self.__mArray.SetName('DisplacementZ')

    self.__chartTable = vtk.vtkTable()
    self.__chartTable.AddColumn(self.__xArray)
    self.__chartTable.AddColumn(self.__yArray)
    self.__chartTable.AddColumn(self.__zArray)
    self.__chartTable.AddColumn(self.__mArray)
    self.__chartTable.SetNumberOfRows(numOfDataNodes)
    
    for i in range(numOfDataNodes):
      self.__chartTable.SetValue(i, 0, float(outputTransformSequenceNode.GetNthIndexValue(i)))
      linearTransformNode = outputTransformSequenceNode.GetNthDataNode(i)
      vtkMatrix = linearTransformNode.GetTransformToParent().GetMatrix()
      self.__chartTable.SetValue(i, 1, vtkMatrix.GetElement(0,3))
      self.__chartTable.SetValue(i, 2, vtkMatrix.GetElement(1,3))
      self.__chartTable.SetValue(i, 3, vtkMatrix.GetElement(2,3))
      
    self.__chart.GetAxis(0).SetTitle('displacement(mm)')
    self.__chart.GetAxis(1).SetTitle('time(s)')
    plot = self.__chart.AddPlot(0)
    if self.chartingDisplayOption == 'LR':
      plot.SetInput(self.__chartTable, 0, 1)
    if self.chartingDisplayOption == 'AP':
      plot.SetInput(self.__chartTable, 0, 2)
    if self.chartingDisplayOption == 'SI':
      plot.SetInput(self.__chartTable, 0, 3)
Example #3
0
    def populateChart(self):
        # strip elements from 2nd 3d view
        # and add our own chart renderer to it
        self.aModeImageNode = slicer.util.getNode('Image_NeedleTip')
        if self.aModeImageNode is None:
            logging.debug(
                "Cannot locate Image_NeedleTip, can't visualize chart")
            return

        self.imageData = self.aModeImageNode.GetImageData()

        if not self.table is None:
            # We already have created all of the things, don't recreate
            self.view.GetInteractor().Initialize()
            self.chart.RecalculateBounds()
            return

        self.table = vtk.vtkTable()
        self.chart = vtk.vtkChartXY()
        self.line = self.chart.AddPlot(0)
        self.view = vtk.vtkContextView()
        self.signalArray = vtk.vtkDoubleArray()
        self.signalArray.SetName("RF Signal")
        self.distanceArray = vtk.vtkDoubleArray()
        self.distanceArray.SetName("Distance (mm)")

        self.imageDimensions = self.imageData.GetDimensions()
        self.signalArray.SetNumberOfTuples(self.imageDimensions[0])
        self.distanceArray.SetNumberOfTuples(self.imageDimensions[0])

        self.table.AddColumn(self.distanceArray)
        self.table.AddColumn(self.signalArray)

        self.line = self.chart.AddPlot(0)
        self.line.SetInputData(self.table, 0, 1)
        self.line.SetColor(0, 255, 0, 255)
        self.line.SetWidth(1.0)

        inc = 1000 * 1480 / (
            2 * 420e6
        )  # distance in mm. The delay distance is added to the increments.  (2e-6*1480/2) +
        distanceDelay = 1000 * 2e-6 * 1480 / 2
        for i in range(self.imageDimensions[0]):
            self.distanceArray.SetComponent(i, 0, distanceDelay + inc * i)

        self.view.GetRenderer().SetBackground(1.0, 1.0, 1.0)
        self.view.GetRenderWindow().SetSize(400, 300)
        # self.contextScene = vtk.vtkContextScene()
        # self.contextScene.AddItem(self.chart)
        # self.contextActor = vtk.vtkContextActor()
        self.view.GetScene().AddItem(self.chart)
        self.view.GetRenderWindow().SetMultiSamples(0)
        # self.layoutManager.threeDWidget(1).threeDView.renderWindow().GetRenderer().GetFirstRenderer().AddActor(self.contextActor)

        self.view.GetInteractor().Initialize()
  def CalculatePlane( self, inPoints, base, dir1, dir2, normal ):

    # Create arrays for the dataset
    points2D = vtk.vtkPoints()
  
    arrayX = vtk.vtkDoubleArray()
    arrayX.SetNumberOfComponents( 1 )
    arrayX.SetName ( 'X' )
    arrayY = vtk.vtkDoubleArray()
    arrayY.SetNumberOfComponents( 1 )
    arrayY.SetName ( 'Y' )
    arrayZ = vtk.vtkDoubleArray()
    arrayZ.SetNumberOfComponents( 1 )
    arrayZ.SetName ( 'Z' )
    
    # Add the points to the table
    for i in range( 0, inPoints.GetNumberOfPoints() ):
    
      currPoint = [ 0, 0, 0 ]
      inPoints.GetPoint( i, currPoint )   
      
      arrayX.InsertNextValue( currPoint[ 0 ] )
      arrayY.InsertNextValue( currPoint[ 1 ] ) 
      arrayZ.InsertNextValue( currPoint[ 2 ] )
    
    # Create a table for the dataset
    table = vtk.vtkTable()
    table.AddColumn( arrayX )
    table.AddColumn( arrayY )
    table.AddColumn( arrayZ )
    
    # Setting up the PCA
    pca = vtk.vtkPCAStatistics()
    pca.SetInputData( vtk.vtkStatisticsAlgorithm.INPUT_DATA, table )
    pca.SetColumnStatus( 'X', 1 )
    pca.SetColumnStatus( 'Y', 1 )
    pca.SetColumnStatus( 'Z', 1 )
    pca.RequestSelectedColumns()
    pca.SetDeriveOption( True )
    pca.Update()
    
    eigvec = vtk.vtkDoubleArray()
    pca.GetEigenvectors( eigvec )
  
    
    eigvec.GetTuple( 0, dir1 )
    eigvec.GetTuple( 1, dir2 )
    eigvec.GetTuple( 2, normal )
  
    mean = self.CalculateMean( inPoints )
    base[0] = mean[0]
    base[1] = mean[1]
    base[2] = mean[2]
Example #5
0
    def onInputChanged(self):
        self.__mvNode = self.__mvSelector.currentNode()

        if self.__mvNode != None:

            Helper.SetBgFgVolumes(self.__mvNode.GetID(), None)

            nFrames = self.__mvNode.GetNumberOfFrames()
            self.__mdSlider.minimum = 0
            self.__mdSlider.maximum = nFrames - 1
            self.__chartTable.SetNumberOfRows(nFrames)

            # if self.__cvn != None:
            #  self.__cvn.SetChartNodeID(self.__cn.GetID())

            self.ctrlFrame.enabled = True
            self.plotFrame.enabled = True
            self.ctrlFrame.collapsed = 0
            self.plotFrame.collapsed = 0

            self.__vfSelector.setCurrentNode(None)

            self.__xArray.SetNumberOfTuples(nFrames)
            self.__xArray.SetNumberOfComponents(1)
            self.__xArray.Allocate(nFrames)
            self.__xArray.SetName('frame')
            self.__yArray.SetNumberOfTuples(nFrames)
            self.__yArray.SetNumberOfComponents(1)
            self.__yArray.Allocate(nFrames)
            self.__yArray.SetName('signal intensity')

            self.__chartTable = vtk.vtkTable()
            self.__chartTable.AddColumn(self.__xArray)
            self.__chartTable.AddColumn(self.__yArray)
            self.__chartTable.SetNumberOfRows(nFrames)

            # get the range of intensities for the
            mvi = self.__mvNode.GetImageData()
            self.__mvRange = [0, 0]
            for f in range(nFrames):
                extract = vtk.vtkImageExtractComponents()
                extract.SetInput(mvi)
                extract.SetComponents(f)
                extract.Update()

                frame = extract.GetOutput()
                frameRange = frame.GetScalarRange()
                self.__mvRange[0] = min(self.__mvRange[0], frameRange[0])
                self.__mvRange[1] = max(self.__mvRange[1], frameRange[1])

            self.__mvLabels = string.split(
                self.__mvNode.GetAttribute('MultiVolume.FrameLabels'), ',')
            if len(self.__mvLabels) != nFrames:
                return
            for l in range(nFrames):
                self.__mvLabels[l] = float(self.__mvLabels[l])

            self.baselineFrames.maximum = nFrames

        else:
            self.ctrlFrame.enabled = False
            self.plotFrame.enabled = False
            self.ctrlFrame.collapsed = 1
            self.plotFrame.collapsed = 1
            self.__mvLabels = []
Example #6
0
    def setup(self):

        self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                            self.onVCMRMLSceneChanged)

        w = qt.QWidget()
        layout = qt.QGridLayout()
        w.setLayout(layout)
        self.layout.addWidget(w)
        w.show()
        self.layout = layout

        # create frames
        self.inputFrame = ctk.ctkCollapsibleButton()
        self.inputFrame.text = "Input"
        self.inputFrame.collapsed = 0
        inputFrameLayout = qt.QFormLayout(self.inputFrame)
        self.layout.addWidget(self.inputFrame)

        self.ctrlFrame = ctk.ctkCollapsibleButton()
        self.ctrlFrame.text = "Frame control"
        self.ctrlFrame.collapsed = 0
        ctrlFrameLayout = qt.QGridLayout(self.ctrlFrame)
        self.layout.addWidget(self.ctrlFrame)

        self.plotFrame = ctk.ctkCollapsibleButton()
        self.plotFrame.text = "Plotting"
        self.plotFrame.collapsed = 0
        plotFrameLayout = qt.QGridLayout(self.plotFrame)
        self.layout.addWidget(self.plotFrame)

        self.plotSettingsFrame = ctk.ctkCollapsibleButton()
        self.plotSettingsFrame.text = "Settings"
        self.plotSettingsFrame.collapsed = 1
        plotSettingsFrameLayout = qt.QGridLayout(self.plotSettingsFrame)
        plotFrameLayout.addWidget(self.plotSettingsFrame, 0, 1)

        label = qt.QLabel('Input multivolume')
        self.__mvSelector = slicer.qMRMLNodeComboBox()
        self.__mvSelector.nodeTypes = ['vtkMRMLMultiVolumeNode']
        self.__mvSelector.setMRMLScene(slicer.mrmlScene)
        self.__mvSelector.connect('mrmlSceneChanged(vtkMRMLScene*)',
                                  self.onVCMRMLSceneChanged)
        self.__mvSelector.connect('currentNodeChanged(vtkMRMLNode*)',
                                  self.onInputChanged)
        self.__mvSelector.addEnabled = 0

        inputFrameLayout.addRow(label, self.__mvSelector)

        label = qt.QLabel('Input secondary multivolume')
        self.fgSelector = slicer.qMRMLNodeComboBox()
        self.fgSelector.nodeTypes = ['vtkMRMLMultiVolumeNode']
        self.fgSelector.setMRMLScene(slicer.mrmlScene)
        self.fgSelector.addEnabled = 0
        self.fgSelector.noneEnabled = 1
        self.fgSelector.toolTip = "Secondary multivolume will be used for the secondary \
      plot in interactive charting. As an example, this can be used to overlay the \
      curve obtained by fitting a model to the data"

        inputFrameLayout.addRow(label, self.fgSelector)

        # TODO: initialize the slider based on the contents of the labels array
        # slider to scroll over metadata stored in the vector container being explored
        self.__mdSlider = ctk.ctkSliderWidget()

        label = qt.QLabel('Current frame number')

        # "play" control
        self.playButton = qt.QPushButton('Play')
        self.playButton.toolTip = 'Iterate over multivolume frames'
        self.playButton.checkable = True

        ctrlFrameLayout.addWidget(label, 0, 0)
        ctrlFrameLayout.addWidget(self.__mdSlider, 0, 1)
        ctrlFrameLayout.addWidget(self.playButton, 0, 2)

        self.playButton.connect('toggled(bool)', self.onPlayButtonToggled)

        self.__mdSlider.connect('valueChanged(double)', self.onSliderChanged)

        label = qt.QLabel('Current frame copy')

        self.__vfSelector = slicer.qMRMLNodeComboBox()
        self.__vfSelector.nodeTypes = ['vtkMRMLScalarVolumeNode']
        self.__vfSelector.setMRMLScene(slicer.mrmlScene)
        self.__vfSelector.connect('mrmlSceneChanged(vtkMRMLScene*)',
                                  self.onVFMRMLSceneChanged)
        self.__vfSelector.addEnabled = 1
        self.__vfSelector.enabled = 0
        # do not show "children" of vtkMRMLScalarVolumeNode
        self.__vfSelector.hideChildNodeTypes = ["vtkMRMLDiffusionWeightedVolumeNode", \
            "vtkMRMLDiffusionTensorVolumeNode", "vtkMRMLVectorVolumeNode"]

        self.extractFrame = False
        self.extractButton = qt.QPushButton('Enable current frame copying')
        self.extractButton.checkable = True
        self.extractButton.connect('toggled(bool)', self.onExtractFrameToggled)

        ctrlFrameLayout.addWidget(label, 1, 0)
        ctrlFrameLayout.addWidget(self.__vfSelector, 1, 1, 1, 2)
        ctrlFrameLayout.addWidget(self.extractButton, 2, 0, 1, 3)

        # initialize slice observers (from DataProbe.py)
        # keep list of pairs: [observee,tag] so they can be removed easily
        self.styleObserverTags = []
        # keep a map of interactor styles to sliceWidgets so we can easily get sliceLogic
        self.sliceWidgetsPerStyle = {}
        self.refreshObservers()

        # label map for probing
        label = qt.QLabel('Probed label volume')
        self.__fSelector = slicer.qMRMLNodeComboBox()
        self.__fSelector.nodeTypes = ['vtkMRMLScalarVolumeNode']
        self.__fSelector.addAttribute('vtkMRMLScalarVolumeNode', 'LabelMap',
                                      '1')
        self.__fSelector.toolTip = 'Label map to be probed'
        self.__fSelector.setMRMLScene(slicer.mrmlScene)
        self.__fSelector.addEnabled = 0
        self.chartButton = qt.QPushButton('Chart')
        self.chartButton.checkable = False
        self.chartButton.connect('clicked()', self.onChartRequested)
        plotSettingsFrameLayout.addWidget(label, 0, 0)
        plotSettingsFrameLayout.addWidget(self.__fSelector, 0, 1)
        plotSettingsFrameLayout.addWidget(self.chartButton, 0, 2)

        self.iCharting = qt.QPushButton()
        self.iCharting.text = 'Enable interactive charting'
        self.iCharting.checkable = True

        plotSettingsFrameLayout.addWidget(self.iCharting, 1, 0, 1, 3)
        self.iCharting.setChecked(True)
        self.iCharting.connect('toggled(bool)',
                               self.onInteractiveChartingChanged)

        groupLabel = qt.QLabel('Interactive plotting mode:')
        self.iChartingMode = qt.QButtonGroup()
        self.iChartingIntensity = qt.QRadioButton('Signal intensity')
        #self.iChartingIntensity.tooltip = 'Plot range adjusted dynamically to the range over the time course for the selected pixel'
        self.iChartingIntensityFixedAxes = qt.QRadioButton(
            'Fixed range intensity')
        #self.iChartingIntensityFixedAxes.tooltip = "If checked, the extent of the vertical axis of the plot will be fixed to the range of the intensities in the input MultiVolume"
        self.iChartingPercent = qt.QRadioButton('Percent change')
        #self.iChartingPercent.tooltip = 'Percent change relative to the average of the first N frames (parameter set below)'
        self.iChartingIntensity.setChecked(1)

        self.groupWidget = qt.QWidget()
        self.groupLayout = qt.QFormLayout(self.groupWidget)
        self.groupLayout.addRow(groupLabel)
        self.groupLayout.addRow(self.iChartingIntensity)
        self.groupLayout.addRow(self.iChartingIntensityFixedAxes)
        self.groupLayout.addRow(self.iChartingPercent)

        self.baselineFrames = qt.QSpinBox()
        self.baselineFrames.minimum = 1
        label = qt.QLabel('Number of frames for baseline calculation')
        self.groupLayout.addRow(label, self.baselineFrames)

        self.xLogScaleCheckBox = qt.QCheckBox()
        self.xLogScaleCheckBox.setChecked(0)
        label = qt.QLabel('Use log scale for X axis')
        self.groupLayout.addRow(self.xLogScaleCheckBox, label)
        self.xLogScaleCheckBox.connect('stateChanged(int)',
                                       self.onXLogScaleRequested)

        self.yLogScaleCheckBox = qt.QCheckBox()
        self.yLogScaleCheckBox.setChecked(0)
        label = qt.QLabel('Use log scale for Y axis')
        self.groupLayout.addRow(self.yLogScaleCheckBox, label)
        self.yLogScaleCheckBox.connect('stateChanged(int)',
                                       self.onYLogScaleRequested)

        plotSettingsFrameLayout.addWidget(self.groupWidget, 2, 0)

        # add chart container widget
        self.__chartView = ctk.ctkVTKChartView(w)
        plotFrameLayout.addWidget(self.__chartView, 3, 0, 1, 3)

        self.__chart = self.__chartView.chart()
        self.__chartTable = vtk.vtkTable()
        self.__xArray = vtk.vtkFloatArray()
        self.__yArray = vtk.vtkFloatArray()
        # will crash if there is no name
        self.__xArray.SetName('')
        self.__yArray.SetName('signal intensity')
        self.__chartTable.AddColumn(self.__xArray)
        self.__chartTable.AddColumn(self.__yArray)
Example #7
0
  def createChart(self, sliceWidget, xy, ignoreCurrentBackground=False):
    if not sliceWidget and not xy:
      return

    sliceLogic = sliceWidget.sliceLogic()

    bgLayer = sliceLogic.GetBackgroundLayer()

    doIJKToRASTransformation = False
    bgVolumeNode = bgLayer.GetVolumeNode()
    if not bgVolumeNode or bgVolumeNode.GetID() != self.__bgMultiVolumeNode.GetID() or \
      bgVolumeNode != self.__bgMultiVolumeNode:
      if not ignoreCurrentBackground:
        return
      else:
        doIJKToRASTransformation = True

    xyz = sliceWidget.sliceView().convertDeviceToXYZ(xy)
    xyToIJK = bgLayer.GetXYToIJKTransform()
    ijkFloat = xyToIJK.TransformDoublePoint(xyz)
    if doIJKToRASTransformation:
      RAStoIJK = vtk.vtkMatrix4x4()
      self.__bgMultiVolumeNode.GetRASToIJKMatrix(RAStoIJK)
      ras = self.xyToRAS(sliceLogic, xy)
      ijkFloat = RAStoIJK.MultiplyPoint([ras[0], ras[1], ras[2], 1])[:3]

    bgijk = self.getIJKIntFromIJKFloat(ijkFloat)
    bgImage = self.__bgMultiVolumeNode.GetImageData()

    if not self.arePixelsWithinImageExtent(bgImage, bgijk):
      self.clearPlots()
      return

    nComponents = self.__bgMultiVolumeNode.GetNumberOfFrames()

    useFg = False
    fgImage = None
    fgijk = None
    if self.__fgMultiVolumeNode:
      fgijkFloat = xyToIJK.TransformDoublePoint(xyz)
      fgijk = self.getIJKIntFromIJKFloat(fgijkFloat)

      fgImage = self.__fgMultiVolumeNode.GetImageData()
      fgChartTable = vtk.vtkTable()
      if fgijk[0] == bgijk[0] and fgijk[1] == bgijk[1] and fgijk[2] == bgijk[2] and \
         fgImage.GetNumberOfScalarComponents() == bgImage.GetNumberOfScalarComponents():
        useFg = True

        fgxArray = vtk.vtkFloatArray()
        self.refreshArray(fgxArray, nComponents, '')

        fgyArray = vtk.vtkFloatArray()
        self.refreshArray(fgyArray, nComponents, '2nd multivolume')

        # will crash if there is no name
        fgChartTable.AddColumn(fgxArray)
        fgChartTable.AddColumn(fgyArray)
        fgChartTable.SetNumberOfRows(nComponents)

    # get the vector of values at IJK
    for c in range(nComponents):
      val = bgImage.GetScalarComponentAsDouble(bgijk[0],bgijk[1],bgijk[2],c)
      if math.isnan(val):
        val = 0
      self.__chartTable.SetValue(c, 0, self.__mvLabels[c])
      self.__chartTable.SetValue(c, 1, val)
      if useFg:
        fgValue = fgImage.GetScalarComponentAsDouble(bgijk[0],bgijk[1],bgijk[2],c)
        if math.isnan(fgValue):
          fgValue = 0
        fgChartTable.SetValue(c,0,self.__mvLabels[c])
        fgChartTable.SetValue(c,1,fgValue)

    self.baselineAverageSignal = 0
    if self.__chartMode == self.PERCENTAGE_CHANGE_MODE:
      self.computePercentageChangeWithRespectToBaseline(self.__bgMultiVolumeNode, self.__chartTable, bgijk)
      if useFg:
        self.computePercentageChangeWithRespectToBaseline(self.__fgMultiVolumeNode, fgChartTable, fgijk)

    self.clearPlots()
    self.setAxesTitle()

    bgPlot = self.chart.AddPlot(vtk.vtkChart.POINTS if useFg else vtk.vtkChart.LINE)
    # bgPlot.SetLabel("Primary multivolume ")
    self.setPlotInputTable(bgPlot, self.__chartTable)

    if useFg:
      fgPlot = self.chart.AddPlot(vtk.vtkChart.LINE)
      # bgPlot.SetLabel("Primary multivolume ")
      self.setPlotInputTable(fgPlot, fgChartTable)
Example #8
0
 def createNewVTKTable(self, xArray, yArray):
   chartTable = vtk.vtkTable()
   chartTable.AddColumn(xArray)
   chartTable.AddColumn(yArray)
   return chartTable
  def onInputChanged(self):
    self.__mvNode = self.__mvSelector.currentNode()

    if self.__mvNode != None:

      Helper.SetBgFgVolumes(self.__mvNode.GetID(), None)

      nFrames = self.__mvNode.GetNumberOfFrames()
      self.__mdSlider.minimum = 0
      self.__mdSlider.maximum = nFrames-1
      self.__chartTable.SetNumberOfRows(nFrames)

      # if self.__cvn != None:
      #  self.__cvn.SetChartNodeID(self.__cn.GetID())

      self.ctrlFrame.enabled = True
      self.plotFrame.enabled = True
      self.ctrlFrame.collapsed = 0
      self.plotFrame.collapsed = 0

      self.__vfSelector.setCurrentNode(None)

      self.__xArray.SetNumberOfTuples(nFrames)
      self.__xArray.SetNumberOfComponents(1)
      self.__xArray.Allocate(nFrames)
      self.__xArray.SetName('frame')
      self.__yArray.SetNumberOfTuples(nFrames)
      self.__yArray.SetNumberOfComponents(1)
      self.__yArray.Allocate(nFrames)
      self.__yArray.SetName('signal intensity')

      self.__chartTable = vtk.vtkTable()
      self.__chartTable.AddColumn(self.__xArray)
      self.__chartTable.AddColumn(self.__yArray)
      self.__chartTable.SetNumberOfRows(nFrames)

      # get the range of intensities for the
      mvi = self.__mvNode.GetImageData()
      self.__mvRange = [0,0]
      for f in range(nFrames):
        extract = vtk.vtkImageExtractComponents()
        extract.SetInput(mvi)
        extract.SetComponents(f)
        extract.Update()

        frame = extract.GetOutput()
        frameRange = frame.GetScalarRange()
        self.__mvRange[0] = min(self.__mvRange[0], frameRange[0])
        self.__mvRange[1] = max(self.__mvRange[1], frameRange[1])

      self.__mvLabels = string.split(self.__mvNode.GetAttribute('MultiVolume.FrameLabels'),',')
      if len(self.__mvLabels) != nFrames:
        return
      for l in range(nFrames):
        self.__mvLabels[l] = float(self.__mvLabels[l])

      self.baselineFrames.maximum = nFrames

    else:
      self.ctrlFrame.enabled = False
      self.plotFrame.enabled = False
      self.ctrlFrame.collapsed = 1
      self.plotFrame.collapsed = 1
      self.__mvLabels = []
Example #10
0
    def setup(self, wName, parent):
        if self.ctrlWidget:
            return

        self.LinkViewers()
        self.numFrames = len(self.nodeImgList[0][0])

        if parent:
            self.ctrlWidget = parent
        else:
            # Create seperate window
            self.ctrlWidget = slicer.qMRMLWidget()
            self.ctrlWidget.setMRMLScene(slicer.mrmlScene)
            self.ctrlWidget.setLayout(qt.QFormLayout())

        self.ctrlWidget.setWindowTitle(wName)
        ctrlLayout = self.ctrlWidget.layout()

        # Create Slider Panel
        self.sliderPanel = qt.QWidget()
        self.sliderPanel.setLayout(qt.QGridLayout())
        ctrlLayout.addWidget(self.sliderPanel)
        sliderLayout = self.sliderPanel.layout()

        if self.numFrames > 1:
            self.ctrlFrameLabel = qt.QLabel('Frame')
            self.ctrlFrameSlider = ctk.ctkSliderWidget()
            self.ctrlFrameSlider.connect('valueChanged(double)',
                                         self.onSliderFrameChanged)
            sliderLayout.addWidget(self.ctrlFrameLabel, 0, 0)
            sliderLayout.addWidget(self.ctrlFrameSlider, 0, 1)

        self.ctrlLevelLabel = qt.QLabel('Level')
        self.ctrlLevelSlider = ctk.ctkSliderWidget()
        self.ctrlLevelSlider.connect('valueChanged(double)',
                                     self.onSliderLevelChanged)
        sliderLayout.addWidget(self.ctrlLevelLabel, 1, 0)
        sliderLayout.addWidget(self.ctrlLevelSlider, 1, 1)

        self.ctrlWindowLabel = qt.QLabel('Window')
        self.ctrlWindowSlider = ctk.ctkSliderWidget()
        self.ctrlWindowSlider.connect('valueChanged(double)',
                                      self.onSliderWindowChanged)
        sliderLayout.addWidget(self.ctrlWindowLabel, 2, 0)
        sliderLayout.addWidget(self.ctrlWindowSlider, 2, 1)

        self.setSliderRangesAndValues()

        if self.sliceNodeList:
            self.orientPanel = qt.QWidget()
            self.orientPanel.setLayout(qt.QGridLayout())
            ctrlLayout.addWidget(self.orientPanel)

            self.orientationButtons = {}
            index = 0
            for orientation in self.orientations:
                self.orientationButtons[orientation] = qt.QRadioButton()
                self.orientationButtons[orientation].text = orientation
                # self.orientationBox.layout().addWidget(self.orientationButtons[orientation])
                self.orientPanel.layout().addWidget(
                    self.orientationButtons[orientation], 0, index)
                self.orientationButtons[orientation].connect(
                    "clicked()", lambda o=orientation: self.setOrientation(o))
                index += 1

        self.setOrientation(self.selectedOrientation)

        if False:
            #self.plotFrame = ctk.ctkCollapsibleButton()
            #self.plotFrame.text = "Plotting"
            #self.plotFrame.collapsed = 0
            self.plotFrame = qt.QWidget()
            plotFrameLayout = qt.QGridLayout(self.plotFrame)
            ctrlLayout.addWidget(self.plotFrame)

            self.plotSettingsFrame = ctk.ctkCollapsibleButton()
            self.plotSettingsFrame.text = "Settings"
            self.plotSettingsFrame.collapsed = 1
            plotSettingsFrameLayout = qt.QGridLayout(self.plotSettingsFrame)
            #plotFrameLayout.addWidget(self.plotSettingsFrame,0,1)

            self.xLogScaleCheckBox = qt.QCheckBox()
            self.xLogScaleCheckBox.setChecked(0)

            self.yLogScaleCheckBox = qt.QCheckBox()
            self.yLogScaleCheckBox.setChecked(0)

            # taken from  https://github.com/fedorov/MultiVolumeExplorer
            self.__chartView = ctk.ctkVTKChartView(self.ctrlWidget)
            # self.plotFrame)
            #  self.ctrlWidget
            plotFrameLayout.addWidget(self.__chartView, 0, 0)

            self.__chart = self.__chartView.chart()
            self.__chartTable = vtk.vtkTable()
            self.__xArray = vtk.vtkFloatArray()
            self.__yArray = vtk.vtkFloatArray()
            # will crash if there is no name
            self.__xArray.SetName('')
            self.__yArray.SetName('signal intensity')
            self.__chartTable.AddColumn(self.__xArray)
            self.__chartTable.AddColumn(self.__yArray)

            self.onInputChanged()
            self.refreshObservers()

        self.buttonPanel = qt.QWidget()
        self.buttonPanel.setLayout(qt.QGridLayout())
        ctrlLayout.addWidget(self.buttonPanel)

        self.exitButton = qt.QPushButton("Exit")
        self.exitButton.toolTip = "Close down slicer."
        self.exitButton.name = "sviewer exit"
        self.buttonPanel.layout().addWidget(self.exitButton, 0, 0)
        self.exitButton.connect('clicked()', exit)

        # do not do ctrlWin.show() here - for some reason window does not pop up then
        return self.ctrlWidget
    def createChart(self, sliceWidget, xy, ignoreCurrentBackground=False):
        if not sliceWidget and not xy:
            return

        sliceLogic = sliceWidget.sliceLogic()

        bgLayer = sliceLogic.GetBackgroundLayer()

        doIJKToRASTransformation = False
        bgVolumeNode = bgLayer.GetVolumeNode()
        if not bgVolumeNode or bgVolumeNode.GetID() != self.__bgMultiVolumeNode.GetID() or \
          bgVolumeNode != self.__bgMultiVolumeNode:
            if not ignoreCurrentBackground:
                return
            else:
                doIJKToRASTransformation = True

        xyz = sliceWidget.sliceView().convertDeviceToXYZ(xy)
        xyToIJK = bgLayer.GetXYToIJKTransform()
        ijkFloat = xyToIJK.TransformDoublePoint(xyz)
        if doIJKToRASTransformation:
            RAStoIJK = vtk.vtkMatrix4x4()
            self.__bgMultiVolumeNode.GetRASToIJKMatrix(RAStoIJK)
            ras = self.xyToRAS(sliceLogic, xy)
            ijkFloat = RAStoIJK.MultiplyPoint([ras[0], ras[1], ras[2], 1])[:3]

        bgijk = self.getIJKIntFromIJKFloat(ijkFloat)
        bgImage = self.__bgMultiVolumeNode.GetImageData()

        if not self.arePixelsWithinImageExtent(bgImage, bgijk):
            self.clearPlots()
            return

        nComponents = self.__bgMultiVolumeNode.GetNumberOfFrames()

        useFg = False
        fgImage = None
        fgijk = None
        if self.__fgMultiVolumeNode:
            fgijkFloat = xyToIJK.TransformDoublePoint(xyz)
            fgijk = self.getIJKIntFromIJKFloat(fgijkFloat)

            fgImage = self.__fgMultiVolumeNode.GetImageData()
            fgChartTable = vtk.vtkTable()
            if fgijk[0] == bgijk[0] and fgijk[1] == bgijk[1] and fgijk[2] == bgijk[2] and \
               fgImage.GetNumberOfScalarComponents() == bgImage.GetNumberOfScalarComponents():
                useFg = True

                fgxArray = vtk.vtkFloatArray()
                self.refreshArray(fgxArray, nComponents, '')

                fgyArray = vtk.vtkFloatArray()
                self.refreshArray(fgyArray, nComponents, '2nd multivolume')

                # will crash if there is no name
                fgChartTable.AddColumn(fgxArray)
                fgChartTable.AddColumn(fgyArray)
                fgChartTable.SetNumberOfRows(nComponents)

        # get the vector of values at IJK
        for c in range(nComponents):
            val = bgImage.GetScalarComponentAsDouble(bgijk[0], bgijk[1],
                                                     bgijk[2], c)
            if math.isnan(val):
                val = 0
            self.__chartTable.SetValue(c, 0, self.__mvLabels[c])
            self.__chartTable.SetValue(c, 1, val)
            if useFg:
                fgValue = fgImage.GetScalarComponentAsDouble(
                    bgijk[0], bgijk[1], bgijk[2], c)
                if math.isnan(fgValue):
                    fgValue = 0
                fgChartTable.SetValue(c, 0, self.__mvLabels[c])
                fgChartTable.SetValue(c, 1, fgValue)

        self.baselineAverageSignal = 0
        if self.__chartMode == self.PERCENTAGE_CHANGE_MODE:
            self.computePercentageChangeWithRespectToBaseline(
                self.__bgMultiVolumeNode, self.__chartTable, bgijk)
            if useFg:
                self.computePercentageChangeWithRespectToBaseline(
                    self.__fgMultiVolumeNode, fgChartTable, fgijk)

        self.clearPlots()
        self.setAxesTitle()

        bgPlot = self.chart.AddPlot(
            vtk.vtkChart.POINTS if useFg else vtk.vtkChart.LINE)
        # bgPlot.SetLabel("Primary multivolume ")
        self.setPlotInputTable(bgPlot, self.__chartTable)

        if useFg:
            fgPlot = self.chart.AddPlot(vtk.vtkChart.LINE)
            # bgPlot.SetLabel("Primary multivolume ")
            self.setPlotInputTable(fgPlot, fgChartTable)
 def createNewVTKTable(self, xArray, yArray):
     chartTable = vtk.vtkTable()
     chartTable.AddColumn(xArray)
     chartTable.AddColumn(yArray)
     return chartTable
Example #13
0
    def setup(self):

        self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                            self.onVCMRMLSceneChanged)

        w = qt.QWidget()
        layout = qt.QGridLayout()
        w.setLayout(layout)
        self.layout.addWidget(w)
        w.show()
        self.layout = layout

        # create frames
        self.inputFrame = ctk.ctkCollapsibleButton()
        self.inputFrame.text = "Input"
        self.inputFrame.collapsed = 0
        inputFrameLayout = qt.QFormLayout(self.inputFrame)
        self.layout.addWidget(self.inputFrame)

        self.ctrlFrame = ctk.ctkCollapsibleButton()
        self.ctrlFrame.text = "Frame control"
        self.ctrlFrame.collapsed = 0
        ctrlFrameLayout = qt.QGridLayout(self.ctrlFrame)
        self.layout.addWidget(self.ctrlFrame)

        self.plotFrame = ctk.ctkCollapsibleButton()
        self.plotFrame.text = "Plotting"
        self.plotFrame.collapsed = 0
        plotFrameLayout = qt.QGridLayout(self.plotFrame)
        self.layout.addWidget(self.plotFrame)

        label = qt.QLabel('Input multivolume')
        self.__mvSelector = slicer.qMRMLNodeComboBox()
        self.__mvSelector.nodeTypes = ['vtkMRMLMultiVolumeNode']
        self.__mvSelector.setMRMLScene(slicer.mrmlScene)
        self.__mvSelector.connect('mrmlSceneChanged(vtkMRMLScene*)',
                                  self.onVCMRMLSceneChanged)
        self.__mvSelector.connect('currentNodeChanged(vtkMRMLNode*)',
                                  self.onInputChanged)
        self.__mvSelector.addEnabled = 0

        inputFrameLayout.addRow(label, self.__mvSelector)
        ##self.layout.addWidget(label)
        ##self.layout.addWidget(self.__mvSelector)

        # TODO: initialize the slider based on the contents of the labels array
        # slider to scroll over metadata stored in the vector container being explored
        self.__mdSlider = ctk.ctkSliderWidget()
        #self.__mdSlider.setRange(0,10)
        #self.__mdSlider.setValue(5)

        label = qt.QLabel('Current frame number')
        ##self.layout.addWidget(label)
        ##self.layout.addWidget(self.__mdSlider)

        # "play" control
        self.playButton = qt.QPushButton('Play')
        self.playButton.toolTip = 'Iterate over multivolume frames'
        self.playButton.checkable = True

        ctrlFrameLayout.addWidget(label, 0, 0)
        ctrlFrameLayout.addWidget(self.__mdSlider, 0, 1)
        ctrlFrameLayout.addWidget(self.playButton, 0, 2)

        self.playButton.connect('toggled(bool)', self.onPlayButtonToggled)

        self.__mdSlider.connect('valueChanged(double)', self.onSliderChanged)

        label = qt.QLabel('Current frame copy')

        self.__vfSelector = slicer.qMRMLNodeComboBox()
        self.__vfSelector.nodeTypes = ['vtkMRMLScalarVolumeNode']
        self.__vfSelector.setMRMLScene(slicer.mrmlScene)
        self.__vfSelector.connect('mrmlSceneChanged(vtkMRMLScene*)',
                                  self.onVFMRMLSceneChanged)
        self.__vfSelector.addEnabled = 1
        self.__vfSelector.enabled = 0
        # do not show "children" of vtkMRMLScalarVolumeNode
        self.__vfSelector.hideChildNodeTypes = ["vtkMRMLDiffusionWeightedVolumeNode", \
            "vtkMRMLDiffusionTensorVolumeNode", "vtkMRMLVectorVolumeNode"]

        self.extractFrame = False
        self.extractButton = qt.QPushButton('Enable current frame copying')
        self.extractButton.checkable = True
        self.extractButton.connect('toggled(bool)', self.onExtractFrameToggled)

        ctrlFrameLayout.addWidget(label, 1, 0)
        ctrlFrameLayout.addWidget(self.__vfSelector, 1, 1, 1, 2)
        ctrlFrameLayout.addWidget(self.extractButton, 2, 0, 1, 3)

        # initialize slice observers (from DataProbe.py)
        # keep list of pairs: [observee,tag] so they can be removed easily
        self.styleObserverTags = []
        # keep a map of interactor styles to sliceWidgets so we can easily get sliceLogic
        self.sliceWidgetsPerStyle = {}
        self.refreshObservers()

        # label map for probing
        label = qt.QLabel('Probed label volume')
        self.__fSelector = slicer.qMRMLNodeComboBox()
        self.__fSelector.nodeTypes = ['vtkMRMLScalarVolumeNode']
        self.__fSelector.addAttribute('vtkMRMLScalarVolumeNode', 'LabelMap',
                                      '1')
        self.__fSelector.toolTip = 'Label map to be probed'
        self.__fSelector.setMRMLScene(slicer.mrmlScene)
        self.__fSelector.addEnabled = 0
        self.__fSelector.connect('currentNodeChanged(vtkMRMLNode*)',
                                 self.onLabelVolumeChanged)
        self.__fSelector.connect('mrmlSceneChanged(vtkMRMLScene*)',
                                 self.onLVMRMLSceneChanged)
        plotFrameLayout.addWidget(label, 0, 0, 1, 1)
        plotFrameLayout.addWidget(self.__fSelector, 0, 1, 1, 2)

        self.iCharting = qt.QPushButton()
        self.iCharting.text = 'Enable interactive charting'
        self.iCharting.checkable = True

        plotFrameLayout.addWidget(self.iCharting, 1, 0, 1, 3)
        self.iCharting.setChecked(True)
        self.iCharting.connect('toggled(bool)',
                               self.onInteractiveChartingChanged)

        label = qt.QLabel("Use intensity range to fix axis extent")
        label.toolTip = "If checked, the extent of the vertical axis of the plot will be fixed to the range of the intensities in the input MultiVolume"
        self.__fixedAxesCheckbox = qt.QCheckBox()
        self.__fixedAxesCheckbox.toolTip = "If checked, the extent of the vertical axis of the plot will be fixed to the range of the intensities in the input MultiVolume"
        self.__fixedAxesCheckbox.checked = False
        plotFrameLayout.addWidget(label, 2, 0)
        plotFrameLayout.addWidget(self.__fixedAxesCheckbox, 2, 1, 1, 2)

        # add chart container widget
        self.__chartView = ctk.ctkVTKChartView(w)
        plotFrameLayout.addWidget(self.__chartView, 3, 0, 1, 3)

        self.__chart = self.__chartView.chart()
        self.__chartTable = vtk.vtkTable()
        self.__xArray = vtk.vtkFloatArray()
        self.__yArray = vtk.vtkFloatArray()
        # will crash if there is no name
        self.__xArray.SetName('')
        self.__yArray.SetName('signal intensity')
        self.__chartTable.AddColumn(self.__xArray)
        self.__chartTable.AddColumn(self.__yArray)
Example #14
0
    def processEvent(self, observee, event):
        if not self.iCharting.checked:
            return

        if self.__mvNode == None:
            return

        mvImage = self.__mvNode.GetImageData()
        nComponents = self.__mvNode.GetNumberOfFrames()

        # TODO: use a timer to delay calculation and compress events
        if event == 'LeaveEvent':
            # reset all the readouts
            # TODO: reset the label text
            return

        if not self.sliceWidgetsPerStyle.has_key(observee):
            return

        sliceWidget = self.sliceWidgetsPerStyle[observee]
        sliceLogic = sliceWidget.sliceLogic()
        interactor = observee.GetInteractor()
        xy = interactor.GetEventPosition()
        xyz = sliceWidget.sliceView().convertDeviceToXYZ(xy)

        ras = sliceWidget.sliceView().convertXYZToRAS(xyz)
        bgLayer = sliceLogic.GetBackgroundLayer()
        fgLayer = sliceLogic.GetForegroundLayer()

        volumeNode = bgLayer.GetVolumeNode()
        fgVolumeNode = self.fgSelector.currentNode()
        if not volumeNode or volumeNode.GetID() != self.__mvNode.GetID():
            return
        if volumeNode != self.__mvNode:
            return

        nameLabel = volumeNode.GetName()
        xyToIJK = bgLayer.GetXYToIJKTransform()
        ijkFloat = xyToIJK.TransformDoublePoint(xyz)
        ijk = []
        for element in ijkFloat:
            try:
                index = int(round(element))
            except ValueError:
                index = 0
            ijk.append(index)

        extent = mvImage.GetExtent()
        if not (ijk[0]>=extent[0] and ijk[0]<=extent[1] and \
           ijk[1]>=extent[2] and ijk[1]<=extent[3] and \
           ijk[2]>=extent[4] and ijk[2]<=extent[5]):
            # pixel outside the valid extent
            return

        useFg = False
        if fgVolumeNode:
            fgxyToIJK = fgLayer.GetXYToIJKTransform()
            fgijkFloat = xyToIJK.TransformDoublePoint(xyz)
            fgijk = []
            for element in fgijkFloat:
                try:
                    index = int(round(element))
                except ValueError:
                    index = 0
                fgijk.append(index)
                fgImage = fgVolumeNode.GetImageData()

            fgChartTable = vtk.vtkTable()
            if fgijk[0] == ijk[0] and fgijk[1] == ijk[1] and fgijk[2] == ijk[2] and \
                fgImage.GetNumberOfScalarComponents() == mvImage.GetNumberOfScalarComponents():
                useFg = True

                fgxArray = vtk.vtkFloatArray()
                fgxArray.SetNumberOfTuples(nComponents)
                fgxArray.SetNumberOfComponents(1)
                fgxArray.Allocate(nComponents)
                fgxArray.SetName('frame')

                fgyArray = vtk.vtkFloatArray()
                fgyArray.SetNumberOfTuples(nComponents)
                fgyArray.SetNumberOfComponents(1)
                fgyArray.Allocate(nComponents)
                fgyArray.SetName('signal intensity')

                # will crash if there is no name
                fgChartTable.AddColumn(fgxArray)
                fgChartTable.AddColumn(fgyArray)
                fgChartTable.SetNumberOfRows(nComponents)

        # get the vector of values at IJK

        for c in range(nComponents):
            val = mvImage.GetScalarComponentAsDouble(ijk[0], ijk[1], ijk[2], c)
            self.__chartTable.SetValue(c, 0, self.__mvLabels[c])
            self.__chartTable.SetValue(c, 1, val)
            if useFg:
                fgValue = fgImage.GetScalarComponentAsDouble(
                    ijk[0], ijk[1], ijk[2], c)
                fgChartTable.SetValue(c, 0, self.__mvLabels[c])
                fgChartTable.SetValue(c, 1, fgValue)

        baselineAverageSignal = 0
        if self.iChartingPercent.checked:
            # check if percent plotting was requested and recalculate
            nBaselines = min(self.baselineFrames.value, nComponents)
            for c in range(nBaselines):
                baselineAverageSignal += mvImage.GetScalarComponentAsDouble(
                    ijk[0], ijk[1], ijk[2], c)
            baselineAverageSignal /= nBaselines
            if baselineAverageSignal != 0:
                for c in range(nComponents):
                    intensity = mvImage.GetScalarComponentAsDouble(
                        ijk[0], ijk[1], ijk[2], c)
                    self.__chartTable.SetValue(
                        c, 1, (intensity / baselineAverageSignal - 1) * 100.)

        self.__chart.RemovePlot(0)
        self.__chart.RemovePlot(0)

        if self.iChartingPercent.checked and baselineAverageSignal != 0:
            self.__chart.GetAxis(0).SetTitle('change relative to baseline, %')
        else:
            self.__chart.GetAxis(0).SetTitle('signal intensity')

        tag = str(
            self.__mvNode.GetAttribute(
                'MultiVolume.FrameIdentifyingDICOMTagName'))
        units = str(
            self.__mvNode.GetAttribute(
                'MultiVolume.FrameIdentifyingDICOMTagUnits'))
        xTitle = tag + ', ' + units
        self.__chart.GetAxis(1).SetTitle(xTitle)
        if self.iChartingIntensityFixedAxes.checked == True:
            self.__chart.GetAxis(0).SetBehavior(vtk.vtkAxis.FIXED)
            self.__chart.GetAxis(0).SetRange(self.__mvRange[0],
                                             self.__mvRange[1])
        else:
            self.__chart.GetAxis(0).SetBehavior(vtk.vtkAxis.AUTO)
        if useFg:
            plot = self.__chart.AddPlot(vtk.vtkChart.POINTS)
            plot.SetInput(self.__chartTable, 0, 1)
            fgplot = self.__chart.AddPlot(vtk.vtkChart.LINE)
            fgplot.SetInput(fgChartTable, 0, 1)
        else:
            plot = self.__chart.AddPlot(vtk.vtkChart.LINE)
            plot.SetInput(self.__chartTable, 0, 1)

        if self.xLogScaleCheckBox.checkState() == 2:
            title = self.__chart.GetAxis(1).GetTitle()
            self.__chart.GetAxis(1).SetTitle('log of ' + title)

        if self.yLogScaleCheckBox.checkState() == 2:
            title = self.__chart.GetAxis(0).GetTitle()
            self.__chart.GetAxis(0).SetTitle('log of ' + title)
Example #15
0
  def __init__(self,param):
    super(LesionFormWidget,self).__init__()

    # parameters node keeps all that is needed to render
    # the form and to store the scores
    self.param = param

    self.widget = qt.QWidget()
    self.layout = qt.QHBoxLayout(self.widget)

    lesionNameWidget = qt.QWidget()
    scoreSheetWidget = qt.QWidget()
    plotWidget = qt.QWidget()

    lnLayout = qt.QVBoxLayout(lesionNameWidget)
    ssLayout = qt.QVBoxLayout(scoreSheetWidget)
    pLayout = qt.QVBoxLayout(plotWidget)

    lesionName = qt.QLabel(self.param.lesionName)
    lnLayout.addWidget(lesionName)

    w = qt.QWidget()
    wl = qt.QHBoxLayout(w)

    for i in range(0,6):
      if i:
        label = qt.QLabel(str(i))
      else:
        label = qt.QLabel('')

      wl.addWidget(label)

    ssLayout.addWidget(w)

    w = qt.QWidget()
    wl = qt.QHBoxLayout(w)

    t2label = qt.QLabel('T2W')
    wl.addWidget(t2label)
    t2radios = []
    self.t2group = qt.QButtonGroup()
    for i in range(1,6):
      t2radios.append(qt.QRadioButton())
      self.t2group.addButton(t2radios[-1],i)
      wl.addWidget(t2radios[-1])
    self.t2group.connect('buttonClicked(int)', self.onT2scoreUpdated)
  
    ssLayout.addWidget(w)
  
    w = qt.QWidget()
    wl = qt.QHBoxLayout(w)
  
    dwilabel = qt.QLabel('DWI')
    wl.addWidget(dwilabel)
    dwiradios = []
    self.dwigroup = qt.QButtonGroup()
    for i in range(1,6):
      dwiradios.append(qt.QRadioButton())
      self.dwigroup.addButton(dwiradios[-1],i)
      wl.addWidget(dwiradios[-1])
    self.dwigroup.connect('buttonClicked(int)', self.onDWIscoreUpdated)
  
    ssLayout.addWidget(w)
  
    w = qt.QWidget()
    wl = qt.QHBoxLayout(w)
  
    dcelabel = qt.QLabel('DCE')
    wl.addWidget(dcelabel)
    dceradios = []
    self.dcegroup = qt.QButtonGroup()
    for i in range(1,6):
      dceradios.append(qt.QRadioButton())
      self.dcegroup.addButton(dceradios[-1],i)
      wl.addWidget(dceradios[-1])
    self.dcegroup.connect('buttonClicked(int)', self.onDCEscoreUpdated)
  
    ssLayout.addWidget(w)
  
    chartView = ctk.ctkVTKChartView(plotWidget)
    chart = chartView.chart()
    table = vtk.vtkTable()
    x = vtk.vtkFloatArray()
    y = vtk.vtkFloatArray()
    x.SetName('time point')
    y.SetName('signal intensity')
    table.AddColumn(x)
    table.AddColumn(y)
  
    table.SetNumberOfRows(100)
    for c in range(len(self.param.x)):
      table.SetValue(c,0,self.param.x[c])
      table.SetValue(c,1,self.param.y[c])
    
    plot = chart.AddPlot(0)
    plot.SetInput(table,0,1)
    chart.AddPlot(0)
  
    cw = qt.QWidget()
    cwl = qt.QVBoxLayout(cw)
    cwl.addWidget(chartView)
    pLayout.addWidget(cw)

    self.layout.addWidget(lesionNameWidget)
    self.layout.addWidget(scoreSheetWidget)
    self.layout.addWidget(plotWidget)
  def setup( self ):

    self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.onVCMRMLSceneChanged)

    w = qt.QWidget()
    layout = qt.QGridLayout()
    w.setLayout(layout)
    self.layout.addWidget(w)
    w.show()
    self.layout = layout

    # create frames
    self.inputFrame = ctk.ctkCollapsibleButton()
    self.inputFrame.text = "Input"
    self.inputFrame.collapsed = 0
    inputFrameLayout = qt.QFormLayout(self.inputFrame)
    self.layout.addWidget(self.inputFrame)


    self.ctrlFrame = ctk.ctkCollapsibleButton()
    self.ctrlFrame.text = "Frame control"
    self.ctrlFrame.collapsed = 0
    ctrlFrameLayout = qt.QGridLayout(self.ctrlFrame)
    self.layout.addWidget(self.ctrlFrame)

    self.plotFrame = ctk.ctkCollapsibleButton()
    self.plotFrame.text = "Plotting"
    self.plotFrame.collapsed = 0
    plotFrameLayout = qt.QGridLayout(self.plotFrame)
    self.layout.addWidget(self.plotFrame)

    self.plotSettingsFrame = ctk.ctkCollapsibleButton()
    self.plotSettingsFrame.text = "Settings"
    self.plotSettingsFrame.collapsed = 1
    plotSettingsFrameLayout = qt.QGridLayout(self.plotSettingsFrame)
    plotFrameLayout.addWidget(self.plotSettingsFrame,0,1)

    label = qt.QLabel('Input multivolume')
    self.__mvSelector = slicer.qMRMLNodeComboBox()
    self.__mvSelector.nodeTypes = ['vtkMRMLMultiVolumeNode']
    self.__mvSelector.setMRMLScene(slicer.mrmlScene)
    self.__mvSelector.connect('mrmlSceneChanged(vtkMRMLScene*)', self.onVCMRMLSceneChanged)
    self.__mvSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onInputChanged)
    self.__mvSelector.addEnabled = 0

    inputFrameLayout.addRow(label, self.__mvSelector)

    label = qt.QLabel('Input secondary multivolume')
    self.fgSelector = slicer.qMRMLNodeComboBox()
    self.fgSelector.nodeTypes = ['vtkMRMLMultiVolumeNode']
    self.fgSelector.setMRMLScene(slicer.mrmlScene)
    self.fgSelector.addEnabled = 0
    self.fgSelector.noneEnabled = 1
    self.fgSelector.toolTip = "Secondary multivolume will be used for the secondary \
      plot in interactive charting. As an example, this can be used to overlay the \
      curve obtained by fitting a model to the data"

    inputFrameLayout.addRow(label, self.fgSelector)

    # TODO: initialize the slider based on the contents of the labels array
    # slider to scroll over metadata stored in the vector container being explored
    self.__mdSlider = ctk.ctkSliderWidget()

    label = qt.QLabel('Current frame number')

    # "play" control
    self.playButton = qt.QPushButton('Play')
    self.playButton.toolTip = 'Iterate over multivolume frames'
    self.playButton.checkable = True

    ctrlFrameLayout.addWidget(label, 0, 0)
    ctrlFrameLayout.addWidget(self.__mdSlider, 0, 1)
    ctrlFrameLayout.addWidget(self.playButton, 0, 2)

    self.playButton.connect('toggled(bool)', self.onPlayButtonToggled)

    self.__mdSlider.connect('valueChanged(double)', self.onSliderChanged)

    label = qt.QLabel('Current frame copy')

    self.__vfSelector = slicer.qMRMLNodeComboBox()
    self.__vfSelector.nodeTypes = ['vtkMRMLScalarVolumeNode']
    self.__vfSelector.setMRMLScene(slicer.mrmlScene)
    self.__vfSelector.connect('mrmlSceneChanged(vtkMRMLScene*)', self.onVFMRMLSceneChanged)
    self.__vfSelector.addEnabled = 1
    self.__vfSelector.enabled = 0
    # do not show "children" of vtkMRMLScalarVolumeNode
    self.__vfSelector.hideChildNodeTypes = ["vtkMRMLDiffusionWeightedVolumeNode", \
        "vtkMRMLDiffusionTensorVolumeNode", "vtkMRMLVectorVolumeNode"]

    self.extractFrame = False
    self.extractButton = qt.QPushButton('Enable current frame copying')
    self.extractButton.checkable = True
    self.extractButton.connect('toggled(bool)', self.onExtractFrameToggled)

    ctrlFrameLayout.addWidget(label, 1, 0)
    ctrlFrameLayout.addWidget(self.__vfSelector,1,1,1,2)
    ctrlFrameLayout.addWidget(self.extractButton,2,0,1,3)

    # initialize slice observers (from DataProbe.py)
    # keep list of pairs: [observee,tag] so they can be removed easily
    self.styleObserverTags = []
    # keep a map of interactor styles to sliceWidgets so we can easily get sliceLogic
    self.sliceWidgetsPerStyle = {}
    self.refreshObservers()

    # label map for probing
    label = qt.QLabel('Probed label volume')
    self.__fSelector = slicer.qMRMLNodeComboBox()
    self.__fSelector.nodeTypes = ['vtkMRMLScalarVolumeNode']
    self.__fSelector.addAttribute('vtkMRMLScalarVolumeNode','LabelMap','1')
    self.__fSelector.toolTip = 'Label map to be probed'
    self.__fSelector.setMRMLScene(slicer.mrmlScene)
    self.__fSelector.addEnabled = 0
    self.chartButton = qt.QPushButton('Chart')
    self.chartButton.checkable = False
    self.chartButton.connect('clicked()', self.onChartRequested)
    plotSettingsFrameLayout.addWidget(label,0,0)
    plotSettingsFrameLayout.addWidget(self.__fSelector,0,1)
    plotSettingsFrameLayout.addWidget(self.chartButton,0,2)

    self.iCharting = qt.QPushButton()
    self.iCharting.text = 'Enable interactive charting'
    self.iCharting.checkable = True

    plotSettingsFrameLayout.addWidget(self.iCharting,1,0,1,3)
    self.iCharting.setChecked(True)
    self.iCharting.connect('toggled(bool)', self.onInteractiveChartingChanged)

    groupLabel = qt.QLabel('Interactive plotting mode:')
    self.iChartingMode = qt.QButtonGroup()
    self.iChartingIntensity = qt.QRadioButton('Signal intensity')
    #self.iChartingIntensity.tooltip = 'Plot range adjusted dynamically to the range over the time course for the selected pixel'
    self.iChartingIntensityFixedAxes = qt.QRadioButton('Fixed range intensity')
    #self.iChartingIntensityFixedAxes.tooltip = "If checked, the extent of the vertical axis of the plot will be fixed to the range of the intensities in the input MultiVolume"
    self.iChartingPercent = qt.QRadioButton('Percent change')
    #self.iChartingPercent.tooltip = 'Percent change relative to the average of the first N frames (parameter set below)'
    self.iChartingIntensity.setChecked(1)

    self.groupWidget = qt.QWidget()
    self.groupLayout = qt.QFormLayout(self.groupWidget)
    self.groupLayout.addRow(groupLabel)
    self.groupLayout.addRow(self.iChartingIntensity)
    self.groupLayout.addRow(self.iChartingIntensityFixedAxes)
    self.groupLayout.addRow(self.iChartingPercent)

    self.baselineFrames = qt.QSpinBox()
    self.baselineFrames.minimum = 1
    label = qt.QLabel('Number of frames for baseline calculation')
    self.groupLayout.addRow(label,self.baselineFrames)

    self.xLogScaleCheckBox = qt.QCheckBox()
    self.xLogScaleCheckBox.setChecked(0)
    label = qt.QLabel('Use log scale for X axis')
    self.groupLayout.addRow(self.xLogScaleCheckBox,label)
    self.xLogScaleCheckBox.connect('stateChanged(int)', self.onXLogScaleRequested)

    self.yLogScaleCheckBox = qt.QCheckBox()
    self.yLogScaleCheckBox.setChecked(0)
    label = qt.QLabel('Use log scale for Y axis')
    self.groupLayout.addRow(self.yLogScaleCheckBox,label)
    self.yLogScaleCheckBox.connect('stateChanged(int)', self.onYLogScaleRequested)

    plotSettingsFrameLayout.addWidget(self.groupWidget,2,0)

    # add chart container widget
    self.__chartView = ctk.ctkVTKChartView(w)
    plotFrameLayout.addWidget(self.__chartView,3,0,1,3)

    self.__chart = self.__chartView.chart()
    self.__chartTable = vtk.vtkTable()
    self.__xArray = vtk.vtkFloatArray()
    self.__yArray = vtk.vtkFloatArray()
    # will crash if there is no name
    self.__xArray.SetName('')
    self.__yArray.SetName('signal intensity')
    self.__chartTable.AddColumn(self.__xArray)
    self.__chartTable.AddColumn(self.__yArray)
  def setup( self ):

    self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.onVCMRMLSceneChanged)

    w = qt.QWidget()
    layout = qt.QGridLayout()
    w.setLayout(layout)
    self.layout.addWidget(w)
    w.show()
    self.layout = layout

    # create frames
    self.inputFrame = ctk.ctkCollapsibleButton()
    self.inputFrame.text = "Input"
    self.inputFrame.collapsed = 0
    inputFrameLayout = qt.QFormLayout(self.inputFrame)
    self.layout.addWidget(self.inputFrame)


    self.ctrlFrame = ctk.ctkCollapsibleButton()
    self.ctrlFrame.text = "Frame control"
    self.ctrlFrame.collapsed = 0
    ctrlFrameLayout = qt.QGridLayout(self.ctrlFrame)
    self.layout.addWidget(self.ctrlFrame)

    self.plotFrame = ctk.ctkCollapsibleButton()
    self.plotFrame.text = "Plotting"
    self.plotFrame.collapsed = 0
    plotFrameLayout = qt.QGridLayout(self.plotFrame)
    self.layout.addWidget(self.plotFrame)

    label = qt.QLabel('Input multivolume')
    self.__mvSelector = slicer.qMRMLNodeComboBox()
    self.__mvSelector.nodeTypes = ['vtkMRMLMultiVolumeNode']
    self.__mvSelector.setMRMLScene(slicer.mrmlScene)
    self.__mvSelector.connect('mrmlSceneChanged(vtkMRMLScene*)', self.onVCMRMLSceneChanged)
    self.__mvSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onInputChanged)
    self.__mvSelector.addEnabled = 0

    inputFrameLayout.addRow(label, self.__mvSelector)
    ##self.layout.addWidget(label)
    ##self.layout.addWidget(self.__mvSelector)


    # TODO: initialize the slider based on the contents of the labels array
    # slider to scroll over metadata stored in the vector container being explored
    self.__mdSlider = ctk.ctkSliderWidget()
    #self.__mdSlider.setRange(0,10)
    #self.__mdSlider.setValue(5)

    label = qt.QLabel('Current frame number')
    ##self.layout.addWidget(label)
    ##self.layout.addWidget(self.__mdSlider)

    # "play" control
    self.playButton = qt.QPushButton('Play')
    self.playButton.toolTip = 'Iterate over multivolume frames'
    self.playButton.checkable = True
    
    ctrlFrameLayout.addWidget(label, 0, 0)
    ctrlFrameLayout.addWidget(self.__mdSlider, 0, 1)
    ctrlFrameLayout.addWidget(self.playButton, 0, 2)
    
    self.playButton.connect('toggled(bool)', self.onPlayButtonToggled)

    self.__mdSlider.connect('valueChanged(double)', self.onSliderChanged)

    label = qt.QLabel('Current frame copy')

    self.__vfSelector = slicer.qMRMLNodeComboBox()
    self.__vfSelector.nodeTypes = ['vtkMRMLScalarVolumeNode']
    self.__vfSelector.setMRMLScene(slicer.mrmlScene)
    self.__vfSelector.connect('mrmlSceneChanged(vtkMRMLScene*)', self.onVFMRMLSceneChanged)
    self.__vfSelector.addEnabled = 1
    self.__vfSelector.enabled = 0
    # do not show "children" of vtkMRMLScalarVolumeNode
    self.__vfSelector.hideChildNodeTypes = ["vtkMRMLDiffusionWeightedVolumeNode", \
        "vtkMRMLDiffusionTensorVolumeNode", "vtkMRMLVectorVolumeNode"]

    self.extractFrame = False
    self.extractButton = qt.QPushButton('Enable current frame copying')
    self.extractButton.checkable = True
    self.extractButton.connect('toggled(bool)', self.onExtractFrameToggled)

    ctrlFrameLayout.addWidget(label, 1, 0)
    ctrlFrameLayout.addWidget(self.__vfSelector,1,1,1,2)
    ctrlFrameLayout.addWidget(self.extractButton,2,0,1,3)

    # initialize slice observers (from DataProbe.py)
    # keep list of pairs: [observee,tag] so they can be removed easily
    self.styleObserverTags = []
    # keep a map of interactor styles to sliceWidgets so we can easily get sliceLogic
    self.sliceWidgetsPerStyle = {}
    self.refreshObservers()

    # label map for probing
    label = qt.QLabel('Probed label volume')
    self.__fSelector = slicer.qMRMLNodeComboBox()
    self.__fSelector.nodeTypes = ['vtkMRMLScalarVolumeNode']
    self.__fSelector.addAttribute('vtkMRMLScalarVolumeNode','LabelMap','1')
    self.__fSelector.toolTip = 'Label map to be probed'
    self.__fSelector.setMRMLScene(slicer.mrmlScene)
    self.__fSelector.addEnabled = 0
    self.__fSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onLabelVolumeChanged)
    self.__fSelector.connect('mrmlSceneChanged(vtkMRMLScene*)', self.onLVMRMLSceneChanged)
    plotFrameLayout.addWidget(label,0,0,1,1)
    plotFrameLayout.addWidget(self.__fSelector,0,1,1,2)

    self.iCharting = qt.QPushButton()
    self.iCharting.text = 'Enable interactive charting'
    self.iCharting.checkable = True

    plotFrameLayout.addWidget(self.iCharting,1,0,1,3)
    self.iCharting.setChecked(True)
    self.iCharting.connect('toggled(bool)', self.onInteractiveChartingChanged)

    label = qt.QLabel("Use intensity range to fix axis extent")
    label.toolTip = "If checked, the extent of the vertical axis of the plot will be fixed to the range of the intensities in the input MultiVolume"
    self.__fixedAxesCheckbox = qt.QCheckBox()
    self.__fixedAxesCheckbox.toolTip = "If checked, the extent of the vertical axis of the plot will be fixed to the range of the intensities in the input MultiVolume"
    self.__fixedAxesCheckbox.checked = False
    plotFrameLayout.addWidget(label, 2, 0)
    plotFrameLayout.addWidget(self.__fixedAxesCheckbox, 2,1,1,2)

    # add chart container widget
    self.__chartView = ctk.ctkVTKChartView(w)
    plotFrameLayout.addWidget(self.__chartView,3,0,1,3)


    self.__chart = self.__chartView.chart()
    self.__chartTable = vtk.vtkTable()
    self.__xArray = vtk.vtkFloatArray()
    self.__yArray = vtk.vtkFloatArray()
    # will crash if there is no name
    self.__xArray.SetName('')
    self.__yArray.SetName('signal intensity')
    self.__chartTable.AddColumn(self.__xArray)
    self.__chartTable.AddColumn(self.__yArray)
  def processEvent(self,observee,event):
    if not self.iCharting.checked:
      return

    if self.__mvNode == None:
      return

    mvImage = self.__mvNode.GetImageData()
    nComponents = self.__mvNode.GetNumberOfFrames()

    # TODO: use a timer to delay calculation and compress events
    if event == 'LeaveEvent':
      # reset all the readouts
      # TODO: reset the label text
      return

    if not self.sliceWidgetsPerStyle.has_key(observee):
      return

    sliceWidget = self.sliceWidgetsPerStyle[observee]
    sliceLogic = sliceWidget.sliceLogic()
    interactor = observee.GetInteractor()
    xy = interactor.GetEventPosition()
    xyz = sliceWidget.sliceView().convertDeviceToXYZ(xy);

    ras = sliceWidget.sliceView().convertXYZToRAS(xyz)
    bgLayer = sliceLogic.GetBackgroundLayer()
    fgLayer = sliceLogic.GetForegroundLayer()

    volumeNode = bgLayer.GetVolumeNode()
    fgVolumeNode = self.fgSelector.currentNode()
    if not volumeNode or volumeNode.GetID() != self.__mvNode.GetID():
      return
    if volumeNode != self.__mvNode:
      return

    nameLabel = volumeNode.GetName()
    xyToIJK = bgLayer.GetXYToIJKTransform()
    ijkFloat = xyToIJK.TransformDoublePoint(xyz)
    ijk = []
    for element in ijkFloat:
      try:
        index = int(round(element))
      except ValueError:
        index = 0
      ijk.append(index)

    extent = mvImage.GetExtent()
    if not (ijk[0]>=extent[0] and ijk[0]<=extent[1] and \
       ijk[1]>=extent[2] and ijk[1]<=extent[3] and \
       ijk[2]>=extent[4] and ijk[2]<=extent[5]):
      # pixel outside the valid extent
      return

    useFg = False
    if fgVolumeNode:
      fgxyToIJK = fgLayer.GetXYToIJKTransform()
      fgijkFloat = xyToIJK.TransformDoublePoint(xyz)
      fgijk = []
      for element in fgijkFloat:
        try:
          index = int(round(element))
        except ValueError:
          index = 0
        fgijk.append(index)
        fgImage = fgVolumeNode.GetImageData()

      fgChartTable = vtk.vtkTable()
      if fgijk[0] == ijk[0] and fgijk[1] == ijk[1] and fgijk[2] == ijk[2] and \
          fgImage.GetNumberOfScalarComponents() == mvImage.GetNumberOfScalarComponents():
        useFg = True

        fgxArray = vtk.vtkFloatArray()
        fgxArray.SetNumberOfTuples(nComponents)
        fgxArray.SetNumberOfComponents(1)
        fgxArray.Allocate(nComponents)
        fgxArray.SetName('frame')

        fgyArray = vtk.vtkFloatArray()
        fgyArray.SetNumberOfTuples(nComponents)
        fgyArray.SetNumberOfComponents(1)
        fgyArray.Allocate(nComponents)
        fgyArray.SetName('signal intensity')
 
        # will crash if there is no name
        fgChartTable.AddColumn(fgxArray)
        fgChartTable.AddColumn(fgyArray)
        fgChartTable.SetNumberOfRows(nComponents)

    # get the vector of values at IJK

    for c in range(nComponents):
      val = mvImage.GetScalarComponentAsDouble(ijk[0],ijk[1],ijk[2],c)
      self.__chartTable.SetValue(c, 0, self.__mvLabels[c])
      self.__chartTable.SetValue(c, 1, val)
      if useFg:
        fgValue = fgImage.GetScalarComponentAsDouble(ijk[0],ijk[1],ijk[2],c)
        fgChartTable.SetValue(c,0,self.__mvLabels[c])
        fgChartTable.SetValue(c,1,fgValue)

    baselineAverageSignal = 0
    if self.iChartingPercent.checked:
      # check if percent plotting was requested and recalculate
      nBaselines = min(self.baselineFrames.value,nComponents)
      for c in range(nBaselines):
        baselineAverageSignal += mvImage.GetScalarComponentAsDouble(ijk[0],ijk[1],ijk[2],c)
      baselineAverageSignal /= nBaselines
      if baselineAverageSignal != 0:
        for c in range(nComponents):
          intensity = mvImage.GetScalarComponentAsDouble(ijk[0],ijk[1],ijk[2],c)
          self.__chartTable.SetValue(c,1,(intensity/baselineAverageSignal-1)*100.)

    self.__chart.RemovePlot(0)
    self.__chart.RemovePlot(0)

    if self.iChartingPercent.checked and baselineAverageSignal != 0:
      self.__chart.GetAxis(0).SetTitle('change relative to baseline, %')
    else:
      self.__chart.GetAxis(0).SetTitle('signal intensity')

    tag = str(self.__mvNode.GetAttribute('MultiVolume.FrameIdentifyingDICOMTagName'))
    units = str(self.__mvNode.GetAttribute('MultiVolume.FrameIdentifyingDICOMTagUnits'))
    xTitle = tag+', '+units
    self.__chart.GetAxis(1).SetTitle(xTitle)
    if self.iChartingIntensityFixedAxes.checked == True:
      self.__chart.GetAxis(0).SetBehavior(vtk.vtkAxis.FIXED)
      self.__chart.GetAxis(0).SetRange(self.__mvRange[0],self.__mvRange[1])
    else:
      self.__chart.GetAxis(0).SetBehavior(vtk.vtkAxis.AUTO)
    if useFg:
      plot = self.__chart.AddPlot(vtk.vtkChart.POINTS)
      plot.SetInput(self.__chartTable, 0, 1)
      fgplot = self.__chart.AddPlot(vtk.vtkChart.LINE)
      fgplot.SetInput(fgChartTable, 0, 1)
    else:
      plot = self.__chart.AddPlot(vtk.vtkChart.LINE)
      plot.SetInput(self.__chartTable, 0, 1)
      
    if self.xLogScaleCheckBox.checkState() == 2:
      title = self.__chart.GetAxis(1).GetTitle()
      self.__chart.GetAxis(1).SetTitle('log of '+title)

    if self.yLogScaleCheckBox.checkState() == 2:
      title = self.__chart.GetAxis(0).GetTitle()
      self.__chart.GetAxis(0).SetTitle('log of '+title)
Example #19
0
    def processEvent(self, observee, event):
        #if not self.iCharting.checked:
        #  return
        fgImages = self.nodeImgList[0]
        mvImage = fgImages[0]
        fgNodes = self.nodeList[0]

        nComponents = self.numFrames

        # TODO: use a timer to delay calculation and compress events
        if event == 'LeaveEvent':
            # reset all the readouts
            # TODO: reset the label text
            return

        if not self.sliceWidgetsPerStyle.has_key(observee):
            return

        sliceWidget = self.sliceWidgetsPerStyle[observee]
        sliceLogic = sliceWidget.sliceLogic()
        interactor = observee.GetInteractor()
        xy = interactor.GetEventPosition()

        coordinates = []
        # we need a 4 element point to be able to multiply further down
        coordinates.append(xy[0])
        coordinates.append(xy[1])
        coordinates.append(0)
        coordinates.append(1)

        xyToRas = sliceLogic.GetSliceNode().GetXYToRAS()
        rasPos = xyToRas.MultiplyPoint(coordinates)
        # VTK_CREATE(vtkMatrix4x4, rasToijk);
        rasToijk = vtk.vtkMatrix4x4()
        fgNodes[0].GetRASToIJKMatrix(rasToijk)
        ijkFloat = rasToijk.MultiplyPoint(rasPos)

        ijk = []
        for element in ijkFloat:
            try:
                index = int(round(element))
            except ValueError:
                index = 0
            ijk.append(index)

        extent = mvImage[0].GetExtent()
        if not (ijk[0]>=extent[0] and ijk[0]<=extent[1] and \
           ijk[1]>=extent[2] and ijk[1]<=extent[3] and \
           ijk[2]>=extent[4] and ijk[2]<=extent[5]):

            return

        nComponents = self.numFrames
        # for testing
        # nComponents=1
        if True:
            fgxArray = vtk.vtkFloatArray()
            fgxArray.SetNumberOfTuples(nComponents)
            fgxArray.SetNumberOfComponents(1)
            fgxArray.Allocate(nComponents)
            fgxArray.SetName('frame')

            fgyArray = vtk.vtkFloatArray()
            fgyArray.SetNumberOfTuples(nComponents)
            fgyArray.SetNumberOfComponents(1)
            fgyArray.Allocate(nComponents)
            fgyArray.SetName('signal intensity')

            # will crash if there is no name
            fgChartTable = vtk.vtkTable()
            fgChartTable.AddColumn(fgxArray)
            fgChartTable.AddColumn(fgyArray)
            fgChartTable.SetNumberOfRows(nComponents)

        # get the vector of values at IJK
        if (self.ctrlLevelSlider.maximum - self.ctrlLevelSlider.minimum) > 20:
            intFlag = True
        else:
            intFlag = False

        disVal = []
        if self.ctrlFrameSlider:
            cInd = int(self.ctrlFrameSlider.value)
        else:
            cInd = 0

        for c in range(nComponents):

            for img in fgImages:
                # for c in range(1):
                iLen = len(img)
                if c < iLen:
                    val = img[c].GetScalarComponentAsDouble(
                        ijk[0], ijk[1], ijk[2], 0)
                else:
                    val = img[iLen - 1].GetScalarComponentAsDouble(
                        ijk[0], ijk[1], ijk[2], 0)

                if intFlag:
                    val = int(val)
                else:
                    val = round(val * 100) / 100.0

                # Kilian:  will only show last image - change later
                self.__chartTable.SetValue(c, 0, self.__mvLabels[c])
                self.__chartTable.SetValue(c, 1, val)

                if cInd == c:
                    disVal.append(val)

            #if useFg:
            #  fgValue = fgImage.GetScalarComponentAsDouble(ijk[0],ijk[1],ijk[2],0)
            #  fgChartTable.SetValue(c,0,self.__mvLabels[c])
            #  fgChartTable.SetValue(c,1,fgValue)

        self.valueFrameValues.setText(disVal)

        # To disable plot uncomment
        # return

        baselineAverageSignal = 0
        # if self.iChartingPercent.checked:
        #   # check if percent plotting was requested and recalculate
        #   nBaselines = min(self.baselineFrames.value,nComponents)
        #   for c in range(nBaselines):
        #     baselineAverageSignal += mvImage[0].GetScalarComponentAsDouble(ijk[0],ijk[1],ijk[2],c)
        #   baselineAverageSignal /= nBaselines
        #   if baselineAverageSignal != 0:
        #     for c in range(nComponents):
        #       intensity = mvImage[0].GetScalarComponentAsDouble(ijk[0],ijk[1],ijk[2],c)
        #       self.__chartTable.SetValue(c,1,(intensity/baselineAverageSignal-1)*100.)

        self.__chart.RemovePlot(0)
        self.__chart.RemovePlot(0)

        #if self.iChartingPercent.checked and baselineAverageSignal != 0:
        #  self.__chart.GetAxis(0).SetTitle('change relative to baseline, %')
        #else:
        self.__chart.GetAxis(0).SetTitle('signal intensity')

        #tag = str(self.__mvNode.GetAttribute('MultiVolume.FrameIdentifyingDICOMTagName'))
        #units = str(self.__mvNode.GetAttribute('MultiVolume.FrameIdentifyingDICOMTagUnits'))
        #xTitle = tag+', '+units
        self.__chart.GetAxis(1).SetTitle("Time")
        #if self.iChartingIntensityFixedAxes.checked == True:

        # self.__chart.GetAxis(0).SetBehavior(vtk.vtkAxis.FIXED)
        # self.__chart.GetAxis(0).SetRange(self.__mvRange[0],self.__mvRange[1])
        # self.__chart.GetAxis(0).SetRange(2000,6000)

        # self.__chart.GetAxis(1).SetBehavior(vtk.vtkAxis.FIXED)
        # self.__chart.GetAxis(1).SetRange(2000,6000)

        #else:
        #  self.__chart.GetAxis(0).SetBehavior(vtk.vtkAxis.AUTO)
        # if useFg:
        useFg = False
        if useFg:
            plot = self.__chart.AddPlot(vtk.vtkChart.POINTS)
            if vtk.VTK_MAJOR_VERSION <= 5:
                plot.SetInput(self.__chartTable, 0, 1)
            else:
                plot.SetInputData(self.__chartTable, 0, 1)
            fgplot = self.__chart.AddPlot(vtk.vtkChart.LINE)
            if vtk.VTK_MAJOR_VERSION <= 5:
                fgplot.SetInput(fgChartTable, 0, 1)
            else:
                fgplot.SetInputData(fgChartTable, 0, 1)
        else:
            plot = self.__chart.AddPlot(vtk.vtkChart.LINE)
            if vtk.VTK_MAJOR_VERSION <= 5:
                plot.SetInput(self.__chartTable, 0, 1)
            else:
                plot.SetInputData(self.__chartTable, 0, 1)

        if self.xLogScaleCheckBox.checkState() == 2:
            title = self.__chart.GetAxis(1).GetTitle()
            self.__chart.GetAxis(1).SetTitle('log of ' + title)

        if self.yLogScaleCheckBox.checkState() == 2:
            title = self.__chart.GetAxis(0).GetTitle()
            self.__chart.GetAxis(0).SetTitle('log of ' + title)