예제 #1
0
    def test_Part1Ruler(self,
                        enableScreenshotsFlag=0,
                        screenshotScaleFactor=1):
        """ Test using rulers
    """
        logic = RSNAQuantTutorialLogic()
        logic.enableScreenshots = enableScreenshotsFlag
        logic.screenshotScaleFactor = screenshotScaleFactor

        self.delayDisplay("Starting the test")

        #
        # first, get some data
        #
        import SampleData
        tumor = SampleData.downloadSample('MRBrainTumor1')

        try:
            # four up view
            layoutManager = slicer.app.layoutManager()
            layoutManager.setLayout(
                slicer.vtkMRMLLayoutNode.SlicerLayoutFourUpView)

            # annotations module
            m = slicer.util.mainWindow()
            m.moduleSelector().selectModule('Annotations')

            # add ruler 1
            rulerNode1 = slicer.vtkMRMLAnnotationRulerNode()
            rulerNode1.SetName("d1")
            rulerNode1.SetPosition1(-7.59519, 43.544, 28.6)
            rulerNode1.SetPosition2(-5.56987, 14.177, 28.6)
            rulerNode1.Initialize(slicer.mrmlScene)
            self.delayDisplay("Ruler 1")

            # add ruler 2
            rulerNode2 = slicer.vtkMRMLAnnotationRulerNode()
            rulerNode2.SetName("d2")
            rulerNode2.SetPosition1(-3.54455, 27.656, 13.1646)
            rulerNode2.SetPosition2(-2.5319, 27.656, 47.5949)
            rulerNode2.Initialize(slicer.mrmlScene)
            self.delayDisplay("Ruler 2")

            # scroll
            annotLogic = slicer.modules.annotations.logic()
            annotLogic.JumpSlicesToAnnotationCoordinate(rulerNode1.GetID())

            # show slices
            redWidget = layoutManager.sliceWidget('Red')
            redWidget.sliceController().setSliceLink(True)
            redWidget.sliceController().setSliceVisible(True)

            logic.takeScreenshot('Ruler',
                                 'Ruler used to measure tumor diameter', -1)

            self.delayDisplay('Test passed!')
        except Exception as e:
            import traceback
            traceback.print_exc()
            self.delayDisplay('Test caused exception!\n' + str(e))
예제 #2
0
  def test_Part1Ruler(self,enableScreenshotsFlag=0,screenshotScaleFactor=1):
    """ Test using rulers
    """
    logic = RSNAQuantTutorialLogic()
    logic.enableScreenshots = enableScreenshotsFlag
    logic.screenshotScaleFactor = screenshotScaleFactor

    self.delayDisplay("Starting the test")

    #
    # first, get some data
    #
    import SampleData
    sampleDataLogic = SampleData.SampleDataLogic()
    tumor = sampleDataLogic.downloadMRBrainTumor1()

    try:
      # four up view
      layoutManager = slicer.app.layoutManager()
      layoutManager.setLayout(slicer.vtkMRMLLayoutNode.SlicerLayoutFourUpView)

      # annotations module
      m = slicer.util.mainWindow()
      m.moduleSelector().selectModule('Annotations')

      # add ruler 1
      rulerNode1 = slicer.vtkMRMLAnnotationRulerNode()
      rulerNode1.SetName("d1")
      rulerNode1.SetPosition1(-7.59519,43.544,28.6)
      rulerNode1.SetPosition2(-5.56987,14.177,28.6)
      rulerNode1.Initialize(slicer.mrmlScene)
      self.delayDisplay("Ruler 1")

      # add ruler 2
      rulerNode2 = slicer.vtkMRMLAnnotationRulerNode()
      rulerNode2.SetName("d2")
      rulerNode2.SetPosition1(-3.54455,27.656,13.1646)
      rulerNode2.SetPosition2(-2.5319,27.656,47.5949)
      rulerNode2.Initialize(slicer.mrmlScene)
      self.delayDisplay("Ruler 2")

      # scroll
      annotLogic = slicer.modules.annotations.logic()
      annotLogic.JumpSlicesToAnnotationCoordinate(rulerNode1.GetID())

      # show slices
      redWidget = layoutManager.sliceWidget('Red')
      redWidget.sliceController().setSliceLink(True)
      redWidget.sliceController().setSliceVisible(True);


      logic.takeScreenshot('Ruler','Ruler used to measure tumor diameter',-1)

      self.delayDisplay('Test passed!')
    except Exception, e:
      import traceback
      traceback.print_exc()
      self.delayDisplay('Test caused exception!\n' + str(e))
예제 #3
0
  def test_SlicerCreateRulerCrashIssue4199(self):
    """ Ideally you should have several levels of tests.  At the lowest level
    tests should exercise the functionality of the logic with different inputs
    (both valid and invalid).  At higher levels your tests should emulate the
    way the user would interact with your code and confirm that it still works
    the way you intended.
    One of the most important features of the tests is that it should alert other
    developers when their changes will have an impact on the behavior of your
    module.  For example, if a developer removes a feature that you depend on,
    your test should break so they know that the feature is needed.
    """

    logic = SlicerCreateRulerCrashIssue4199Logic()

    self.delayDisplay("Starting the test")

    slicer.util.selectModule('Welcome')

    # Add a ruler
    rulerNode = slicer.vtkMRMLAnnotationRulerNode()
    rulerNode.SetPosition1(0, 0, 0)
    rulerNode.SetPosition2(1, 1, 1)
    rulerNode.Initialize(slicer.mrmlScene)

    # Enter the Annotations module
    slicer.util.selectModule('Annotations')

    # If test reach this point without crashing it is a success

    self.delayDisplay('Test passed!')
예제 #4
0
    def test_LineIntersityProfile1(self):
        """ Ideally you should have several levels of tests.  At the lowest level
        tests should exercise the functionality of the logic with different inputs
        (both valid and invalid).  At higher levels your tests should emulate the
        way the user would interact with your code and confirm that it still works
        the way you intended.
        One of the most important features of the tests is that it should alert other
        developers when their changes will have an impact on the behavior of your
        module.  For example, if a developer removes a feature that you depend on,
        your test should break so they know that the feature is needed.
        """

        self.delayDisplay("Starting the test")
        #
        # first, get some data
        #
        import urllib
        downloads = (
            ('http://slicer.kitware.com/midas3/download?items=5767',
             'FA.nrrd', slicer.util.loadVolume),
        )

        for url, name, loader in downloads:
            filePath = slicer.app.temporaryPath + '/' + name
            if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
                logging.info(
                    'Requesting download %s from %s...\n' % (name, url))
                urllib.urlretrieve(url, filePath)
            if loader:
                logging.info('Loading %s...' % (name,))
                loader(filePath)
        self.delayDisplay('Finished with download and loading')

        volumeNode = slicer.util.getNode(pattern="FA")
        logic = LineIntersityProfileLogic()
        self.assertTrue(logic.hasImageData(volumeNode))
        # self.delayDisplay('Test passed!')

        # Add Test
        # Initialise rule node in a know location
        rulerNode = slicer.vtkMRMLAnnotationRulerNode()
        slicer.mrmlScene.AddNode(rulerNode)
        rulerNode.SetPosition1(-65, 110, 60)
        rulerNode.SetPosition2(-15, 60, 60)
        rulerNode.SetName('Test')

        # Initialise input selectors
        moduleWidget = slicer.modules.LineIntersityProfileWidget
        # Note: the end has no "()", or a __init__ function required!

        moduleWidget.rulerSelector.setCurrentNode(rulerNode)
        moduleWidget.inputSelector1.setCurrentNode(volumeNode)
        moduleWidget.inputSelector2.setCurrentNode(volumeNode)

        self.delayDisplay("Inputs initialised!")

        # run the logic with the initialised inputs
        moduleWidget.onApplyButton()

        self.delayDisplay("if you see a ruler and a plot - test passed!")
  def test_SlicerCreateRulerCrashIssue4199(self):
    """ Ideally you should have several levels of tests.  At the lowest level
    tests should exercise the functionality of the logic with different inputs
    (both valid and invalid).  At higher levels your tests should emulate the
    way the user would interact with your code and confirm that it still works
    the way you intended.
    One of the most important features of the tests is that it should alert other
    developers when their changes will have an impact on the behavior of your
    module.  For example, if a developer removes a feature that you depend on,
    your test should break so they know that the feature is needed.
    """

    logic = SlicerCreateRulerCrashIssue4199Logic()

    self.delayDisplay("Starting the test")

    slicer.util.selectModule('Welcome')

    # Add a ruler
    rulerNode = slicer.vtkMRMLAnnotationRulerNode()
    rulerNode.SetPosition1(0, 0, 0)
    rulerNode.SetPosition2(1, 1, 1)
    rulerNode.Initialize(slicer.mrmlScene)

    # Enter the Annotations module
    slicer.util.selectModule('Annotations')

    # If test reach this point without crashing it is a success

    self.delayDisplay('Test passed!')
예제 #6
0
  def test_LineIntensityProfile1(self):
    """ Ideally you should have several levels of tests.  At the lowest level
    tests should exercise the functionality of the logic with different inputs
    (both valid and invalid).  At higher levels your tests should emulate the
    way the user would interact with your code and confirm that it still works
    the way you intended.
    One of the most important features of the tests is that it should alert other
    developers when their changes will have an impact on the behavior of your
    module.  For example, if a developer removes a feature that you depend on,
    your test should break so they know that the feature is needed.
    """

    self.delayDisplay("Starting the test")
    #
    # first, get some data
    #
    import urllib
    downloads = (
        ('http://slicer.kitware.com/midas3/download?items=5767', 'FA.nrrd', slicer.util.loadVolume),
        )

    for url,name,loader in downloads:
      filePath = slicer.app.temporaryPath + '/' + name
      if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
        logging.info('Requesting download %s from %s...\n' % (name, url))
        urllib.urlretrieve(url, filePath)
      if loader:
        logging.info('Loading %s...' % (name,))
        loader(filePath)
    self.delayDisplay('Finished with download and loading')

    volumeNode = slicer.util.getNode(pattern="FA")
    logic = LineIntensityProfileLogic()
    self.assertIsNotNone( logic.hasImageData(volumeNode) )
    
    #initialize ruler in a known location
    
    rulerNode = slicer.vtkMRMLAnnotationRulerNode()
    slicer.mrmlScene.AddNode(rulerNode)
    rulerNode.SetPosition1(-65,110,60)
    rulerNode.SetPosition2(-15,60,60)
    rulerNode.SetName('Test')
    
    # initialize input selectors
    
    moduleWidget = slicer.modules.LineIntensityProfileWidget
    moduleWidget.rulerSelector.setCurrentNode(rulerNode)
    moduleWidget.inputSelector1.setCurrentNode(volumeNode)
    moduleWidget.inputSelector2.setCurrentNode(volumeNode)
    
    self.delayDisplay('inputs Initialized')
    
    #run the logic with initialized inputs
    
    moduleWidget.onApplyButton()
    
    self.delayDisplay('If you see a ruler and a plot - test passed')
예제 #7
0
def TestRulerAdd(renameFlag=1, visibilityFlag=1, numToAdd=20):
    print("numToAdd = ", numToAdd)
    if renameFlag > 0:
        print("Index\tTime to add ruler\tDelta between adds\tTime to rename ruler\tDelta between renames")
        print("%(index)04s\t" % {'index': "i"}, "t\tdt\tt\tdt")
    else:
        print("Index\tTime to add ruler\tDelta between adds")
        print("%(index)04s\t" % {'index': "i"}, "t\tdt")
    r1 = 0
    a1 = 0
    s1 = 0
    r2 = 1
    a2 = 1
    s2 = 1
    t1 = 0
    t2 = 0
    t3 = 0
    t4 = 0
    timeToAddThisRuler = 0
    timeToAddLastRuler = 0
    timeToRenameThisRuler = 0
    timeToRenameLastRuler = 0
    # iterate over the number of rulers to add
    for i in range(numToAdd):
        # print "i = ", i, "/", numToAdd, ", r = ", r, ", a = ", a, ", s = ", s
        rulerNode = slicer.vtkMRMLAnnotationRulerNode()
        rulerNode.SetPosition1(r1, a1, s1)
        rulerNode.SetPosition2(r2, a2, s2)
        t1 = time.process_time()
        rulerNode.Initialize(slicer.mrmlScene)
        t2 = time.process_time()
        timeToAddThisRuler = t2 - t1
        dt = timeToAddThisRuler - timeToAddLastRuler
        if renameFlag > 0:
            t3 = time.process_time()
            rulerNode.SetName(str(i))
            t4 = time.process_time()
            timeToRenameThisRuler = t4 - t3
            dt2 = timeToRenameThisRuler - timeToRenameLastRuler
            print('%(index)04d\t' % {'index': i}, timeToAddThisRuler, "\t", dt, "\t", timeToRenameThisRuler, "\t", dt2)
            timeToRenameLastRuler = timeToRenameThisRuler
        else:
            print('%(index)04d\t' % {'index': i}, timeToAddThisRuler, "\t", dt)
        r1 = r1 + 1.0
        a1 = a1 + 1.0
        s1 = s1 + 1.0
        r2 = r2 + 1.5
        a2 = a2 + 1.5
        s2 = s2 + 1.5
        timeToAddLastRuler = timeToAddThisRuler
예제 #8
0
  def findAxisOfMotion(self, origins):
    #Following guide from: http://sebastianraschka.com/Articles/2014_pca_step_by_step.html

    #scale factor for better display:
    scale = 100

    #Calculate mean position
    meanVector = [0, 0 ,0]
    for i in range(3):
      meanVector[i] = np.mean(origins[i, :])


    #Computing covariance matrix
    convMatrix = np.cov([origins[0, :], origins[1, :], origins[2, :]])

    #Get eigenvectors
    eig_val, eig_vec = np.linalg.eig(convMatrix)

    # Make a list of (eigenvalue, eigenvector) tuples
    eig_pairs = [(np.abs(eig_val[i]), eig_vec[:,i]) for i in range(len(eig_val))]

    # Sort the (eigenvalue, eigenvector) tuples from high to low
    eig_pairs.sort()
    # eig_pairs.reverse()
    matrix_w = np.hstack((eig_pairs[0][1].reshape(3, 1),
                          eig_pairs[1][1].reshape(3, 1),
                          eig_pairs[2][1].reshape(3, 1)))
    print('Matrix W:\n', matrix_w)

    #Create linear transform for contour propagation

    vtkMatrix = vtk.vtkMatrix4x4()
    transform = slicer.vtkMRMLLinearTransformNode()
    slicer.mrmlScene.AddNode(transform)

    for i in range(3):
      for j in range(3):
        vtkMatrix.SetElement(j, i, matrix_w[i, j])

    transform.SetAndObserveMatrixTransformFromParent(vtkMatrix)

    #Plot eigenvectors from mean position
    fiducials = slicer.vtkMRMLMarkupsFiducialNode()
    displayNode = slicer.vtkMRMLMarkupsDisplayNode()
        # vtkNew<vtkMRMLMarkupsFiducialStorageNode> wFStorageNode;
    slicer.mrmlScene.AddNode(displayNode)
    slicer.mrmlScene.AddNode(fiducials)
    fiducials.SetAndObserveDisplayNodeID(displayNode.GetID())
    fiducials.AddFiducialFromArray(meanVector, "Mean Position")
    for i in range(len(eig_vec)):
      # fiducials.AddFiducialFromArray(meanVector + scale * eig_vec[i], " P " + str(i+1))
      #Plot ruler
      ruler = slicer.vtkMRMLAnnotationRulerNode()
      displayRuler = slicer.vtkMRMLAnnotationLineDisplayNode()
      displayRuler.SetLabelVisibility(0)
      displayRuler.SetMaxTicks(0)
      displayRuler.SetLineWidth(5)
      slicer.mrmlScene.AddNode(displayRuler)
      slicer.mrmlScene.AddNode(ruler)
      ruler.SetAndObserveDisplayNodeID(displayRuler.GetID())
      ruler.SetPosition1(meanVector)
      ruler.SetPosition2(meanVector + scale * eig_vec[i])

    return matrix_w  
 def get3DEuclideanDistance(pos1, pos2):
     rulerNode = slicer.vtkMRMLAnnotationRulerNode()
     rulerNode.SetPosition1(pos1)
     rulerNode.SetPosition2(pos2)
     distance3D = rulerNode.GetDistanceMeasurement()
     return distance3D
예제 #10
0
 def get3DEuclideanDistance(pos1, pos2):
   rulerNode = slicer.vtkMRMLAnnotationRulerNode()
   rulerNode.SetPosition1(pos1)
   rulerNode.SetPosition2(pos2)
   distance3D = rulerNode.GetDistanceMeasurement()
   return distance3D
    def loadAdditionalMeasurements(self, srUID):
        """
    Loads length measements as annotation rulers
    TODO: need to generalize to other report contents
    """

        srFilePath = slicer.dicomDatabase.fileForInstance(srUID)
        sr = dicom.read_file(srFilePath)

        if not self.isConcept(sr, "imagingMeasurementReport"):
            return sr

        contents = {}
        measurements = []
        contents['measurements'] = measurements
        for item in sr.ContentSequence:
            if self.isConcept(item, "personObserver"):
                contents['personObserver'] = item.PersonName
            if self.isConcept(item, "imagingMeasuremnts"):
                for contentItem in item.ContentSequence:
                    if self.isConcept(contentItem, "measurementGroup"):
                        measurement = {}
                        for measurementItem in contentItem.ContentSequence:
                            if self.isConcept(measurementItem,
                                              "trackingIdentifier"):
                                measurement[
                                    'trackingIdentifier'] = measurementItem.TextValue
                            if self.isConcept(measurementItem,
                                              "trackingUniqueIdentifier"):
                                measurement[
                                    'trackingUniqueIdentifier'] = measurementItem.UID
                            if self.isConcept(measurementItem, "findingSite"):
                                measurement[
                                    'findingSite'] = measurementItem.ConceptCodeSequence[
                                        0].CodeMeaning
                            if self.isConcept(measurementItem, "length"):
                                for lengthItem in measurementItem.ContentSequence:
                                    measurement[
                                        'polyline'] = lengthItem.GraphicData
                                    for selectionItem in lengthItem.ContentSequence:
                                        if selectionItem.RelationshipType == "SELECTED FROM":
                                            for reference in selectionItem.ReferencedSOPSequence:
                                                measurement[
                                                    'referencedSOPInstanceUID'] = reference.ReferencedSOPInstanceUID
                                                if hasattr(
                                                        reference,
                                                        "ReferencedFrameNumber"
                                                ) and reference.ReferencedFrameNumber != "1":
                                                    print(
                                                        'Error - only single frame references supported'
                                                    )
                        measurements.append(measurement)

        for measurement in contents['measurements']:
            rulerNode = slicer.vtkMRMLAnnotationRulerNode()
            rulerNode.SetLocked(True)
            rulerNode.SetName(contents['personObserver'])

            referenceFilePath = slicer.dicomDatabase.fileForInstance(
                measurement['referencedSOPInstanceUID'])
            reference = dicom.read_file(referenceFilePath)
            origin = numpy.array(reference.ImagePositionPatient)
            alongColumnVector = numpy.array(
                reference.ImageOrientationPatient[:3])
            alongRowVector = numpy.array(reference.ImageOrientationPatient[3:])
            alongColumnVector *= reference.PixelSpacing[1]
            alongRowVector *= reference.PixelSpacing[0]
            col1, row1, col2, row2 = measurement['polyline']
            lpsToRAS = numpy.array([-1, -1, 1])
            p1 = (origin + col1 * alongColumnVector +
                  row1 * alongRowVector) * lpsToRAS
            p2 = (origin + col2 * alongColumnVector +
                  row2 * alongRowVector) * lpsToRAS
            rulerNode.SetPosition1(*p1)
            rulerNode.SetPosition2(*p2)

            rulerNode.Initialize(slicer.mrmlScene)
            colorIndex = 1 + len(
                slicer.util.getNodesByClass('vtkMRMLAnnotationRulerNode'))
            colorNode = slicer.util.getNode("GenericAnatomyColors")
            color = [
                0,
            ] * 4
            colorNode.GetColor(colorIndex, color)
            rulerNode.GetDisplayNode().SetColor(*color[:3])
            rulerNode.GetAnnotationTextDisplayNode().SetColor(*color[:3])
            rulerNode.GetAnnotationPointDisplayNode().SetColor(*color[:3])
            rulerNode.GetAnnotationPointDisplayNode().SetGlyphScale(2)
            rulerNode.GetAnnotationLineDisplayNode().SetLabelPosition(
                random.random())