def setupDisplayNode(self, displayNode=None, starBurst=False): if not displayNode: displayNode = slicer.vtkMRMLMarkupsDisplayNode() slicer.mrmlScene.AddNode(displayNode) displayNode.SetTextScale(0) displayNode.SetGlyphScale(2.5) if starBurst: displayNode.SetGlyphType(slicer.vtkMRMLAnnotationPointDisplayNode.StarBurst2D) return displayNode
def cloneFiducials(original, cloneName, keepDisplayNode=False): clone = slicer.vtkMRMLMarkupsFiducialNode() clone.Copy(original) clone.SetName(cloneName) slicer.mrmlScene.AddNode(clone) if not keepDisplayNode: displayNode = slicer.vtkMRMLMarkupsDisplayNode() slicer.mrmlScene.AddNode(displayNode) clone.SetAndObserveDisplayNodeID(displayNode.GetID()) return clone
def run(self, numToAdd=100, rOffset=0, usefewerModifyCalls=0): """ Run the actual algorithm """ print('Running test to add %s fidicuals' % (numToAdd, )) print('Index\tTime to add fid\tDelta between adds') print("%(index)04s\t" % {'index': "i"}, "t\tdt'") r = rOffset a = 0 s = 0 t1 = 0 t2 = 0 t3 = 0 t4 = 0 timeToAddThisFid = 0 timeToAddLastFid = 0 testStartTime = time.clock() displayNode = slicer.vtkMRMLMarkupsDisplayNode() slicer.mrmlScene.AddNode(displayNode) fidNode = slicer.vtkMRMLMarkupsFiducialNode() slicer.mrmlScene.AddNode(fidNode) fidNode.SetAndObserveDisplayNodeID(displayNode.GetID()) if usefewerModifyCalls == 1: print("Start modify") mod = fidNode.StartModify() import random # iterate over the number of fiducials to add for i in range(numToAdd): # print "i = ", i, "/", numToAdd, ", r = ", r, ", a = ", a, ", s = ", s t1 = time.clock() fidNode.AddFiducial(r, a, s) t2 = time.clock() timeToAddThisFid = t2 - t1 dt = timeToAddThisFid - timeToAddLastFid #print '%(index)04d\t' % {'index': i}, timeToAddThisFid, "\t", dt r = float(i) / numToAdd * 100.0 - 50.0 + random.uniform( -20.0, 20.0) a = float(i) / numToAdd * 100.0 - 50.0 + random.uniform( -20.0, 20.0) s = random.uniform(-20.0, 20.0) timeToAddLastFid = timeToAddThisFid if usefewerModifyCalls == 1: fidNode.EndModify(mod) testEndTime = time.clock() testTime = testEndTime - testStartTime print("Total time to add ", numToAdd, " = ", testTime) return True
def run(self,numToAdd=100,rOffset=0,usefewerModifyCalls=0): """ Run the actual algorithm """ print('Running test to add %s fidicuals' % (numToAdd,)) print('Index\tTime to add fid\tDelta between adds') print("%(index)04s\t" % {'index': "i"}, "t\tdt'") r = rOffset a = 0 s = 0 t1 = 0 t2 = 0 t3 = 0 t4 = 0 timeToAddThisFid = 0 timeToAddLastFid = 0 testStartTime = time.clock() displayNode = slicer.vtkMRMLMarkupsDisplayNode() slicer.mrmlScene.AddNode(displayNode) fidNode = slicer.vtkMRMLMarkupsFiducialNode() slicer.mrmlScene.AddNode(fidNode) fidNode.SetAndObserveDisplayNodeID(displayNode.GetID()) if usefewerModifyCalls == 1: print("Start modify") mod = fidNode.StartModify() import random # iterate over the number of fiducials to add for i in range(numToAdd): # print "i = ", i, "/", numToAdd, ", r = ", r, ", a = ", a, ", s = ", s t1 = time.clock() fidNode.AddFiducial(r,a,s) t2 = time.clock() timeToAddThisFid = t2 - t1 dt = timeToAddThisFid - timeToAddLastFid #print '%(index)04d\t' % {'index': i}, timeToAddThisFid, "\t", dt r = float(i)/numToAdd * 100.0 - 50.0 + random.uniform(-20.0, 20.0) a = float(i)/numToAdd * 100.0 - 50.0 + random.uniform(-20.0, 20.0) s = random.uniform(-20.0, 20.0) timeToAddLastFid = timeToAddThisFid if usefewerModifyCalls == 1: fidNode.EndModify(mod) testEndTime = time.clock() testTime = testEndTime - testStartTime print("Total time to add ",numToAdd," = ", testTime) return True
def createNewMarkupNode(self): # Create empty markup fiducial node if self.segmentMarkupNode is None: displayNode = slicer.vtkMRMLMarkupsDisplayNode() displayNode.SetTextScale(0) slicer.mrmlScene.AddNode(displayNode) self.segmentMarkupNode = slicer.vtkMRMLMarkupsFiducialNode() self.segmentMarkupNode.SetName('C') slicer.mrmlScene.AddNode(self.segmentMarkupNode) self.segmentMarkupNode.SetAndObserveDisplayNodeID( displayNode.GetID()) self.setAndObserveSegmentMarkupNode(self.segmentMarkupNode) self.updateGUIFromMRML()
def onImageChanged2(self): self.InputRegistrationTransformNodeX = slicer.vtkMRMLLinearTransformNode() slicer.mrmlScene.AddNode(self.InputRegistrationTransformNodeX) if self.imageNode2 is not None: self.imageNode2.SetAndObserveTransformNodeID(None) self.imageNode2 = None self.imageNode2 = self.imageSelector2.currentNode() if self.imageNode2 is None: print('Please select the right volume') if self.imageNode2 is not None: self.cropping = 1 self.imageNode2 = self.imageSelector2.currentNode() self.clippingModel2 = slicer.vtkMRMLModelNode() self.clippingModel.SetName('Clipping Model 2') slicer.mrmlScene.AddNode(self.clippingModel2) self.displayNode2 = slicer.vtkMRMLMarkupsDisplayNode() slicer.mrmlScene.AddNode(self.displayNode2) self.inputMarkup2 = slicer.vtkMRMLMarkupsFiducialNode() self.inputMarkup2.SetName('C') slicer.mrmlScene.AddNode(self.inputMarkup2) self.inputMarkup2.SetAndObserveDisplayNodeID(self.displayNode2.GetID()) self.inputMarkup2.AddFiducial(234,509,-0.5) self.inputMarkup2.AddFiducial(234,509,0.0) self.inputMarkup2.AddFiducial(500,130,0) self.inputMarkup2.AddFiducial(242,36,0) self.inputMarkup2.AddFiducial(-26,162,0) self.inputMarkup2.SetDisplayVisibility(0) self.outputVolume2 = slicer.vtkMRMLScalarVolumeNode() slicer.mrmlScene.AddNode(self.outputVolume2) self.logic.updateModelFromMarkup(self.inputMarkup2,self.clippingModel2) self.logic.clipVolumeWithModel(self.imageNode2, self.clippingModel2, True, 255, self.outputVolume2) self.logic.showInSliceViewers(self.outputVolume2, ["Yellow"]) self.cropping == 0 self.rightMat.SetElement(0,0,0) self.rightMat.SetElement(2,0,-1) self.rightMat.SetElement(1,1,-1) self.rightMat.SetElement(0,2,-1) self.rightMat.SetElement(2,2,0) self.rightMat.SetElement(1,3,520) self.rightMat.SetElement(2,3,230) self.rightTransform.PostMultiply() self.rightTransform.Identity() self.rightTransform.Concatenate(self.rightMat) self.outputVolume2.GetDisplayNode().SetAutoWindowLevel(0) self.outputVolume2.GetDisplayNode().SetWindowLevelMinMax(25,100) self.yellowWidget.sliceLogic().GetSliceCompositeNode().SetBackgroundVolumeID(self.outputVolume2.GetID()) self.resliceLogic.SetDriverForSlice(self.outputVolume2.GetID(), slicer.mrmlScene.GetNodeByID('vtkMRMLSliceNodeYellow')) self.resliceLogic.SetModeForSlice(self.resliceLogic.MODE_TRANSVERSE, slicer.mrmlScene.GetNodeByID('vtkMRMLSliceNodeYellow')) self.clippingModel2.SetDisplayVisibility(False) slicer.app.layoutManager().sliceWidget('Yellow').sliceLogic().GetSliceNode().SetSliceVisible(True) slicer.app.layoutManager().sliceWidget("Yellow").sliceController().fitSliceToBackground() self.outputVolume2.SetAndObserveTransformNodeID(self.InputRegistrationTransformNodeX.GetID()) self.InputRegistrationTransformNodeX.SetMatrixTransformToParent(self.rightTransform.GetMatrix()) if self.imageNode2 is None: self.cropping = 1 self.imageNode2 = self.imageSelector2.currentNode() self.clippingModel2 = slicer.vtkMRMLModelNode() self.clippingModel.SetName('Clipping Model 2') slicer.mrmlScene.AddNode(self.clippingModel2) self.displayNode2 = slicer.vtkMRMLMarkupsDisplayNode() slicer.mrmlScene.AddNode(self.displayNode2) self.inputMarkup2 = slicer.vtkMRMLMarkupsFiducialNode() self.inputMarkup2.SetName('C') slicer.mrmlScene.AddNode(self.inputMarkup2) self.inputMarkup2.SetAndObserveDisplayNodeID(self.displayNode2.GetID()) self.inputMarkup2.AddFiducial(234,509,-0.5) self.inputMarkup2.AddFiducial(234,509,0.0) self.inputMarkup2.AddFiducial(500,130,0) self.inputMarkup2.AddFiducial(242,36,0) self.inputMarkup2.AddFiducial(-26,162,0) self.inputMarkup2.SetDisplayVisibility(0) self.outputVolume2 = slicer.vtkMRMLScalarVolumeNode() slicer.mrmlScene.AddNode(self.outputVolume2) self.logic.updateModelFromMarkup(self.inputMarkup2,self.clippingModel2) self.logic.clipVolumeWithModel(self.imageNode2, self.clippingModel2, True, 255, self.outputVolume2) self.logic.showInSliceViewers(self.outputVolume2, ["Yellow"]) self.cropping = 0 self.rightMat.SetElement(0,0,0) self.rightMat.SetElement(2,0,-1) self.rightMat.SetElement(1,1,-1) self.rightMat.SetElement(0,2,-1) self.rightMat.SetElement(2,2,0) self.rightMat.SetElement(1,3,520) self.rightMat.SetElement(2,3,230) self.rightTransform.PostMultiply() self.rightTransform.Identity() self.rightTransform.Concatenate(self.rightMat) self.outputVolume2.GetDisplayNode().SetAutoWindowLevel(0) self.outputVolume2.GetDisplayNode().SetWindowLevelMinMax(25,100) self.yellowWidget.sliceLogic().GetSliceCompositeNode().SetBackgroundVolumeID(self.outputVolume2.GetID()) self.resliceLogic.SetDriverForSlice(self.outputVolume2.GetID(), slicer.mrmlScene.GetNodeByID('vtkMRMLSliceNodeYellow')) self.resliceLogic.SetModeForSlice(self.resliceLogic.MODE_TRANSVERSE, slicer.mrmlScene.GetNodeByID('vtkMRMLSliceNodeYellow')) self.clippingModel2.SetDisplayVisibility(False) slicer.app.layoutManager().sliceWidget('Yellow').sliceLogic().GetSliceNode().SetSliceVisible(True) slicer.app.layoutManager().sliceWidget("Yellow").sliceController().fitSliceToBackground() self.outputVolume2.SetAndObserveTransformNodeID(self.InputRegistrationTransformNodeX.GetID()) self.InputRegistrationTransformNodeX.SetMatrixTransformToParent(self.rightTransform.GetMatrix())
def run(self): """ Run the actual algorithm """ print('Running test of the markups in different views') # # first load the data # print("Getting MR Head Volume") import SampleData mrHeadVolume = SampleData.downloadSample("MRHead") # # link the viewers # sliceLogic = slicer.app.layoutManager().sliceWidget('Red').sliceLogic() compositeNode = sliceLogic.GetSliceCompositeNode() compositeNode.SetLinkedControl(1) # # MR Head in the background # sliceLogic.StartSliceCompositeNodeInteraction(1) compositeNode.SetBackgroundVolumeID(mrHeadVolume.GetID()) sliceLogic.EndSliceCompositeNodeInteraction() # # switch to conventional layout # lm = slicer.app.layoutManager() lm.setLayout(2) # create a fiducial list displayNode = slicer.vtkMRMLMarkupsDisplayNode() slicer.mrmlScene.AddNode(displayNode) fidNode = slicer.vtkMRMLMarkupsFiducialNode() slicer.mrmlScene.AddNode(fidNode) fidNode.SetAndObserveDisplayNodeID(displayNode.GetID()) # make it active selectionNode = slicer.mrmlScene.GetNodeByID( "vtkMRMLSelectionNodeSingleton") if (selectionNode is not None): selectionNode.SetReferenceActivePlaceNodeID(fidNode.GetID()) # add some known points to it eye1 = [33.4975, 79.4042, -10.2143] eye2 = [-31.283, 80.9652, -16.2143] nose = [4.61944, 114.526, -33.2143] index = fidNode.AddFiducialFromArray(eye1) fidNode.SetNthFiducialLabel(index, "eye-1") index = fidNode.AddFiducialFromArray(eye2) fidNode.SetNthFiducialLabel(index, "eye-2") # hide the second eye as a test of visibility flags fidNode.SetNthFiducialVisibility(index, 0) index = fidNode.AddFiducialFromArray(nose) fidNode.SetNthFiducialLabel(index, "nose") self.delayDisplay("Placed 3 fiducials") # self.printViewAndSliceNodes() if self.widgetVisible(fidNode, 'vtkMRMLViewNode1') == 0: self.delayDisplay("Test failed: widget is not visible in view 1") # self.printViewNodeIDs(displayNode) return False # # switch to 2 3D views layout # lm.setLayout(15) self.delayDisplay("Switched to 2 3D views") # self.printViewAndSliceNodes() if self.widgetVisible(fidNode, 'vtkMRMLViewNode1') == 0 or self.widgetVisible( fidNode, 'vtkMRMLViewNode2') == 0: self.delayDisplay( "Test failed: widget is not visible in view 1 and 2") # self.printViewNodeIDs(displayNode) return False # # show only in view 2 # displayNode.AddViewNodeID("vtkMRMLViewNode2") self.delayDisplay("Showing only in view 2") if self.widgetVisible(fidNode, 'vtkMRMLViewNode1') == 1: self.delayDisplay( "Test failed: widget is not supposed to be visible in view 1") # self.printViewNodeIDs(displayNode) return False if self.widgetVisible(fidNode, 'vtkMRMLViewNode2') == 0: self.delayDisplay("Test failed: widget is not visible in view 2") # self.printViewNodeIDs(displayNode) return False # # remove it so show in all # displayNode.RemoveAllViewNodeIDs() self.delayDisplay("Showing in both views") if self.widgetVisible(fidNode, 'vtkMRMLViewNode1') == 0 or self.widgetVisible( fidNode, 'vtkMRMLViewNode2') == 0: self.delayDisplay( "Test failed: widget is not visible in view 1 and 2") self.printViewNodeIDs(displayNode) return False # # show only in view 1 # displayNode.AddViewNodeID("vtkMRMLViewNode1") self.delayDisplay("Showing only in view 1") if self.widgetVisible(fidNode, 'vtkMRMLViewNode2') == 1: self.delayDisplay( "Test failed: widget is not supposed to be visible in view 2") # self.printViewNodeIDs(displayNode) return False if self.widgetVisible(fidNode, 'vtkMRMLViewNode1') == 0: self.delayDisplay("Test failed: widget is not visible in view 1") # self.printViewNodeIDs(displayNode) return False # switch back to conventional lm.setLayout(2) self.delayDisplay("Switched back to conventional layout") # self.printViewAndSliceNodes() # test of the visibility in slice views displayNode.RemoveAllViewNodeIDs() # jump to the last fiducial slicer.modules.markups.logic().JumpSlicesToNthPointInMarkup( fidNode.GetID(), index, 1) # refocus the 3D cameras as well slicer.modules.markups.logic().FocusCamerasOnNthPointInMarkup( fidNode.GetID(), index) # show only in red displayNode.AddViewNodeID('vtkMRMLSliceNodeRed') self.delayDisplay("Show only in red slice") if self.widgetVisibleOnSlice(fidNode, 'vtkMRMLSliceNodeRed') != 1: self.delayDisplay("Test failed: widget not displayed on red slice") # self.printViewNodeIDs(displayNode) return False # remove all, add green # print 'before remove all, after added red' # self.printViewNodeIDs(displayNode) displayNode.RemoveAllViewNodeIDs() # print 'after removed all' # self.printViewNodeIDs(displayNode) displayNode.AddViewNodeID('vtkMRMLSliceNodeGreen') self.delayDisplay('Show only in green slice') if self.widgetVisibleOnSlice( fidNode, 'vtkMRMLSliceNodeRed') != 0 or self.widgetVisibleOnSlice( fidNode, 'vtkMRMLSliceNodeGreen') != 1: self.delayDisplay( "Test failed: widget not displayed only on green slice") print '\tred = ', self.widgetVisibleOnSlice( fidNode, 'vtkMRMLSliceNodeRed') print '\tgreen =', self.widgetVisibleOnSlice( fidNode, 'vtkMRMLSliceNodeGreen') self.printViewNodeIDs(displayNode) return False return True
def run(self,enableScreenshots=0,screenshotScaleFactor=1): """ Run the actual algorithm """ self.delayDisplay('Running test of the Neurosurgical Planning tutorial') self.enableScreenshots = enableScreenshots self.screenshotScaleFactor = screenshotScaleFactor # conventional layout lm = slicer.app.layoutManager() lm.setLayout(2) moduleSelector = slicer.util.mainWindow().moduleSelector() # # first load the data # if self.enableScreenshots == 1: # for the tutorial, do it through the welcome module moduleSelector.selectModule('Welcome') self.delayDisplay("Screenshot") self.takeScreenshot('NeurosurgicalPlanning-Welcome','Welcome module',-1) else: # otherwise show the sample data module moduleSelector.selectModule('SampleData') # use the sample data module logic to load data for the self test import SampleData sampleDataLogic = SampleData.SampleDataLogic() self.delayDisplay("Getting Baseline volume") baselineVolume = sampleDataLogic.downloadWhiteMatterExplorationBaselineVolume() self.delayDisplay("Getting DTI volume") dtiVolume = sampleDataLogic.downloadWhiteMatterExplorationDTIVolume() self.takeScreenshot('NeurosurgicalPlanning-Loaded','Data loaded',-1) # # link the viewers # if self.enableScreenshots == 1: # for the tutorial, pop up the linking control sliceController = slicer.app.layoutManager().sliceWidget("Red").sliceController() popupWidget = sliceController.findChild("ctkPopupWidget") if popupWidget != None: popupWidget.pinPopup(1) self.takeScreenshot('NeurosurgicalPlanning-Link','Link slice viewers',-1) popupWidget.pinPopup(0) sliceLogic = slicer.app.layoutManager().sliceWidget('Red').sliceLogic() compositeNode = sliceLogic.GetSliceCompositeNode() compositeNode.SetLinkedControl(1) # # baseline in the background # sliceLogic.StartSliceCompositeNodeInteraction(1) compositeNode.SetBackgroundVolumeID(baselineVolume.GetID()) sliceLogic.EndSliceCompositeNodeInteraction() self.takeScreenshot('NeurosurgicalPlanning-Baseline','Baseline in background',-1) # # adjust window level on baseline # moduleSelector.selectModule('Volumes') baselineDisplay = baselineVolume.GetDisplayNode() baselineDisplay.SetAutoWindowLevel(0) baselineDisplay.SetWindow(2600) baselineDisplay.SetLevel(1206) self.takeScreenshot('NeurosurgicalPlanning-WindowLevel','Set W/L on baseline',-1) # # switch to red slice only # lm.setLayout(6) self.takeScreenshot('NeurosurgicalPlanning-RedSliceOnly','Set layout to Red Slice only',-1) # # segmentation of tumour # # # create a label map and set it for editing # volumesLogic = slicer.modules.volumes.logic() baselineVolumeLabel = volumesLogic.CreateAndAddLabelVolume( slicer.mrmlScene, baselineVolume, baselineVolume.GetName() + '-label' ) baselineDisplayNode = baselineVolumeLabel.GetDisplayNode() baselineDisplayNode.SetAndObserveColorNodeID('vtkMRMLColorTableNodeFileGenericAnatomyColors.txt') selectionNode = slicer.app.applicationLogic().GetSelectionNode() selectionNode.SetReferenceActiveVolumeID(baselineVolume.GetID()) selectionNode.SetReferenceActiveLabelVolumeID(baselineVolumeLabel.GetID()) slicer.app.applicationLogic().PropagateVolumeSelection(0) # # editor module # moduleSelector.selectModule('Editor') self.takeScreenshot('NeurosurgicalPlanning-Editor','Showing Editor Module',-1) # set the slice offset so drawing is right sliceNode = sliceLogic.GetSliceNode() sliceOffset = 58.7 sliceNode.SetSliceOffset(sliceOffset) # # paint # parameterNode = EditUtil.getParameterNode() paintEffect = EditorLib.PaintEffectOptions() paintEffect.setMRMLDefaults() paintEffect.__del__() sliceWidget = lm.sliceWidget('Red') paintTool = EditorLib.PaintEffectTool(sliceWidget) self.takeScreenshot('NeurosurgicalPlanning-Paint','Paint tool in Editor Module',-1) # # paint in cystic part of tumor, using converstion from RAS coords to # avoid slice widget size differences # EditUtil.setLabel(293) displayCoords = self.rasToDisplay(-7.4, 71, sliceOffset) paintTool.paintAddPoint(displayCoords[0], displayCoords[1]) displayCoords = self.rasToDisplay(-11, 73, sliceOffset) paintTool.paintAddPoint(displayCoords[0], displayCoords[1]) displayCoords = self.rasToDisplay(-12, 85, sliceOffset) paintTool.paintAddPoint(displayCoords[0], displayCoords[1]) displayCoords = self.rasToDisplay(-13, 91, sliceOffset) paintTool.paintAddPoint(displayCoords[0], displayCoords[1]) displayCoords = self.rasToDisplay(-15, 78, sliceOffset) paintTool.paintAddPoint(displayCoords[0], displayCoords[1]) paintTool.paintApply() self.takeScreenshot('NeurosurgicalPlanning-PaintCystic','Paint cystic part of tumor',-1) # # paint in solid part of tumor # EditUtil.setLabel(7) displayCoords = self.rasToDisplay(-0.5 , 118.5, sliceOffset) paintTool.paintAddPoint(displayCoords[0], displayCoords[1]) displayCoords = self.rasToDisplay(-7.4 , 116, sliceOffset) paintTool.paintAddPoint(displayCoords[0], displayCoords[1]) paintTool.paintApply() self.takeScreenshot('NeurosurgicalPlanning-PaintSolid','Paint solid part of tumor',-1) # # paint around the tumor # EditUtil.setLabel(295) rMax = 25 rMin = -50 aMax = 145 aMin = 50 rasStep = 5 # draw the top and bottom for r in range(rMin, rMax, rasStep): displayCoords = self.rasToDisplay(r, aMin, sliceOffset) paintTool.paintAddPoint(displayCoords[0], displayCoords[1]) displayCoords = self.rasToDisplay(r, aMax, sliceOffset) paintTool.paintAddPoint(displayCoords[0], displayCoords[1]) # draw the left and right for a in range(aMin, aMax, rasStep): displayCoords = self.rasToDisplay(rMin, a, sliceOffset) paintTool.paintAddPoint(displayCoords[0], displayCoords[1]) displayCoords = self.rasToDisplay(rMax, a, sliceOffset) paintTool.paintAddPoint(displayCoords[0], displayCoords[1]) paintTool.paintApply() self.takeScreenshot('NeurosurgicalPlanning-PaintAround','Paint around tumor',-1) # # clean up after painting # paintTool.cleanup() paintTool = None # # Grow cut # growCutLogic = EditorLib.GrowCutEffectLogic(sliceWidget.sliceLogic()) growCutLogic.growCut() self.takeScreenshot('NeurosurgicalPlanning-Growcut','Growcut',-1) # # Merge split volume # slicer.util.selectModule('Editor') slicer.util.findChildren(text='Split Merge Volume')[0].clicked() self.takeScreenshot('NeurosurgicalPlanning-SplitMerge','SplitMerge',-1) # # go to the data module # moduleSelector.selectModule('Data') self.takeScreenshot('NeurosurgicalPlanning-SplitMergeData','SplitMerge results in Data',-1) # # Ventricles Segmentation # moduleSelector.selectModule('Editor') # # select the label volume with the area around the tumor slicer.util.findChildren(name='PerStructureVolumesFrame')[0].collapsed = False treeView = slicer.util.findChildren(name='StructuresView')[0] selection = qt.QItemSelection() # selecting the last split volume in the third row row = 2 rowStart = treeView.model().index(row,0) rowEnd = treeView.model().index(row,treeView.model().columnCount() - 1) # rowSel = qt.QItemSelection(rowStart, rowEnd) selection.select(rowStart, rowEnd) # backup: select the label map in the slice logic too baselinelabel295 = slicer.mrmlScene.GetFirstNodeByName("BaselineVolume-region 3-label") sliceLogic.StartSliceCompositeNodeInteraction(1) compositeNode.SetLabelVolumeID(baselinelabel295.GetID()) sliceLogic.EndSliceCompositeNodeInteraction() self.takeScreenshot('NeurosurgicalPlanning-SelOutside','Select outside region',-1) # # Threshold tool # slicer.modules.EditorWidget.toolsBox.selectEffect('ThresholdEffect') parameterNode = EditUtil.getParameterNode() parameterNode.SetParameter('ThresholdEffect,min', str(1700)) slicer.modules.EditorWidget.toolsBox.currentTools[0].apply() self.takeScreenshot('NeurosurgicalPlanning-Ventricles','Ventricles segmentation',-1) # # Save Islands # slicer.modules.EditorWidget.toolsBox.selectEffect('SaveIslandEffect') saveIslandLogic = EditorLib.SaveIslandEffectLogic(sliceWidget.sliceLogic()) displayCoords = self.rasToDisplay(25.3, 5.8, sliceOffset) xy = (displayCoords[0], displayCoords[1]) saveIslandLogic.saveIsland(xy) self.takeScreenshot('NeurosurgicalPlanning-SaveIsland','Ventricles save island',-1) # # Merge and build # slicer.util.findChildren(text='Merge And Build')[0].clicked() # # switch to conventional layout # lm.setLayout(2) self.takeScreenshot('NeurosurgicalPlanning-MergeAndBuild','Merged and built models',-1) # # Tractography label map seeding # # # select label volume with label 293, in the second row # row = 1 rowStart = treeView.model().index(row,0) rowEnd = treeView.model().index(row,treeView.model().columnCount() - 1) # rowSel = qt.QItemSelection(rowStart, rowEnd) selection.select(rowStart, rowEnd) # backup: select the label map in the slice logic too baselinelabel293 = slicer.mrmlScene.GetFirstNodeByName("BaselineVolume-region 1-label") sliceLogic.StartSliceCompositeNodeInteraction(1) compositeNode.SetLabelVolumeID(baselinelabel293.GetID()) sliceLogic.EndSliceCompositeNodeInteraction() self.takeScreenshot('NeurosurgicalPlanning-SelCystic','Select cystic region',-1) # # Dilate # slicer.modules.EditorWidget.toolsBox.selectEffect('DilateEffect') EditUtil.setLabel(293) self.takeScreenshot('NeurosurgicalPlanning-Dilate','Dilate tool',-1) # tutorial says to click apply three times for d in range (1,3): print d # slicer.util.findChildren(name='DilateEffectOptionsApply')[0].clicked() # slicer.modules.EditorWidget.toolsBox.currentTools[0].apply() slicer.modules.EditorWidget.toolsBox.currentOption.onApply() self.takeScreenshot('NeurosurgicalPlanning-Dilated','Dilated tumor',-1) # # Tractography Label Map Seeding module # moduleSelector.selectModule('TractographyLabelMapSeeding') self.takeScreenshot('NeurosurgicalPlanning-LabelMapSeedingModule','Showing Tractography Label Seeding Module',-1) tractographyLabelSeeding = slicer.modules.tractographylabelmapseeding parameters = {} parameters['InputVolume'] = dtiVolume.GetID() baselinelabel293 = slicer.mrmlScene.GetFirstNodeByName("BaselineVolume-region 1-label") # VTK6 TODO - set 'InputROIPipelineInfo' parameters['InputROI'] = baselinelabel293.GetID() fibers = slicer.vtkMRMLFiberBundleNode() slicer.mrmlScene.AddNode(fibers) parameters['OutputFibers'] = fibers.GetID() parameters['UseIndexSpace'] = 1 parameters['StoppingValue'] = 0.15 parameters['ROIlabel'] = 293 parameters['StoppingMode'] = 'FractionalAnisotropy' # defaults # parameters['ClTh'] = 0.3 # parameters['MinimumLength'] = 20 # parameters['MaximumLength'] = 800 # parameters['StoppingCurvature'] = 0.7 # parameters['IntegrationStepLength'] = 0.5 # parameters['SeedSpacing'] = 2 # and run it slicer.cli.run(tractographyLabelSeeding, None, parameters) self.takeScreenshot('NeurosurgicalPlanning-LabelMapSeeding','Showing Tractography Label Seeding Results',-1) # # tractography fiducial seeding # moduleSelector.selectModule('TractographyInteractiveSeeding') self.takeScreenshot('NeurosurgicalPlanning-TIS','Showing Tractography Interactive Seeding Module',-1) # DTI in background sliceLogic.StartSliceCompositeNodeInteraction(1) compositeNode.SetBackgroundVolumeID(dtiVolume.GetID()) sliceLogic.EndSliceCompositeNodeInteraction() # DTI visible in 3D sliceNode = sliceLogic.GetSliceNode() sliceLogic.StartSliceNodeInteraction(128) sliceNode.SetSliceVisible(1) sliceLogic.EndSliceNodeInteraction() self.takeScreenshot('NeurosurgicalPlanning-TIS-DTI','DTI volume with Tractography Interactive Seeding Module',-1) # place a fiducial displayNode = slicer.vtkMRMLMarkupsDisplayNode() slicer.mrmlScene.AddNode(displayNode) fidNode = slicer.vtkMRMLMarkupsFiducialNode() fidNode.SetName('F') slicer.mrmlScene.AddNode(fidNode) fidNode.SetAndObserveDisplayNodeID(displayNode.GetID()) r = 28.338526 a = 34.064367 s = sliceOffset fidNode.AddFiducial(r,a,s) # make it active selectionNode = slicer.mrmlScene.GetNodeByID("vtkMRMLSelectionNodeSingleton") if (selectionNode != None): selectionNode.SetReferenceActivePlaceNodeID(fidNode.GetID()) self.takeScreenshot('NeurosurgicalPlanning-TIS-Fid1','Fiducial in Tractography Interactive Seeding Module',-1) # set up the arguments wr = slicer.modules.tractographyinteractiveseeding.widgetRepresentation() wr.setDiffusionTensorVolumeNode(dtiVolume) # create a fiber bundle fiducialFibers = slicer.vtkMRMLFiberBundleNode() slicer.mrmlScene.AddNode(fiducialFibers) wr.setFiberBundleNode(fiducialFibers) wr.setSeedingNode(fidNode) wr.setMinimumPath(10) wr.setStoppingValue(0.15) self.takeScreenshot('NeurosurgicalPlanning-TIS-Args','Tractography Interactive Seeding arguments',-1) self.delayDisplay("Moving the fiducial") for y in range(-20, 100, 5): msg = "Moving the fiducial to y = " + str(y) self.delayDisplay(msg,250) fidNode.SetNthFiducialPosition(0, r, y, s) self.takeScreenshot('NeurosurgicalPlanning-TIS-Moved','Moved fiducial and did Tractography Interactive Seeding',-1) return True
def run(self): """ Run the actual algorithm """ print('Running test of the markups in compare viewers') # # first load the data # import SampleData sampleDataLogic = SampleData.SampleDataLogic() print("Getting MR Head Volume") mrHeadVolume = sampleDataLogic.downloadMRHead() # # link the viewers # sliceLogic = slicer.app.layoutManager().sliceWidget('Red').sliceLogic() compositeNode = sliceLogic.GetSliceCompositeNode() compositeNode.SetLinkedControl(1) # # MR Head in the background # sliceLogic.StartSliceCompositeNodeInteraction(1) compositeNode.SetBackgroundVolumeID(mrHeadVolume.GetID()) sliceLogic.EndSliceCompositeNodeInteraction() # # switch to conventional layout # lm = slicer.app.layoutManager() lm.setLayout(2) # create a fiducial list displayNode = slicer.vtkMRMLMarkupsDisplayNode() slicer.mrmlScene.AddNode(displayNode) fidNode = slicer.vtkMRMLMarkupsFiducialNode() slicer.mrmlScene.AddNode(fidNode) fidNode.SetAndObserveDisplayNodeID(displayNode.GetID()) # make it active selectionNode = slicer.mrmlScene.GetNodeByID( "vtkMRMLSelectionNodeSingleton") if (selectionNode is not None): selectionNode.SetReferenceActivePlaceNodeID(fidNode.GetID()) # add some known points to it eye1 = [33.4975, 79.4042, -10.2143] eye2 = [-31.283, 80.9652, -16.2143] nose = [4.61944, 114.526, -33.2143] index = fidNode.AddFiducialFromArray(eye1) fidNode.SetNthFiducialLabel(index, "eye-1") index = fidNode.AddFiducialFromArray(eye2) fidNode.SetNthFiducialLabel(index, "eye-2") index = fidNode.AddFiducialFromArray(nose) fidNode.SetNthFiducialLabel(index, "nose") self.logicDelayDisplay("Placed 3 fiducials") # # switch to 2 viewers compare layout # lm.setLayout(12) self.logicDelayDisplay("Switched to Compare 2 viewers") # # get compare slice composite node # compareLogic1 = slicer.app.layoutManager().sliceWidget( 'Compare1').sliceLogic() compareCompositeNode1 = compareLogic1.GetSliceCompositeNode() # set MRHead in the background compareLogic1.StartSliceCompositeNodeInteraction(1) compareCompositeNode1.SetBackgroundVolumeID(mrHeadVolume.GetID()) compareLogic1.EndSliceCompositeNodeInteraction() compareLogic1.FitSliceToAll() # make it visible in 3D compareLogic1.GetSliceNode().SetSliceVisible(1) # scroll to a fiducial location compareLogic1.StartSliceOffsetInteraction() compareLogic1.SetSliceOffset(eye1[2]) compareLogic1.EndSliceOffsetInteraction() self.logicDelayDisplay("MH Head in background, scrolled to a fiducial") # scroll around through the range of points offset = nose[2] while offset < eye1[2]: compareLogic1.StartSliceOffsetInteraction() compareLogic1.SetSliceOffset(offset) compareLogic1.EndSliceOffsetInteraction() msg = "Scrolled to " + str(offset) self.logicDelayDisplay(msg, 250) offset += 1.0 # switch back to conventional lm.setLayout(2) self.logicDelayDisplay("Switched back to conventional layout") # switch to compare grid lm.setLayout(23) compareLogic1.FitSliceToAll() self.logicDelayDisplay("Switched to Compare grid") # switch back to conventional lm.setLayout(2) self.logicDelayDisplay("Switched back to conventional layout") return True
def visualizeNewSrep(self, filename): """ Parse header.xml file, create models from the data, and visualize it. """ # 1. parse header file tree = ET.parse(filename) upFileName = '' crestFileName = '' downFileName = '' nCols = 0 nRows = 0 headerFolder = os.path.dirname(filename) for child in tree.getroot(): if child.tag == 'upSpoke': if os.path.isabs(child.text): upFileName = os.path.join(headerFolder, child.text) upFileName = os.path.join(headerFolder, child.text) elif child.tag == 'downSpoke': downFileName = os.path.join(headerFolder, child.text) elif child.tag == 'crestSpoke': crestFileName = os.path.join(headerFolder, child.text) elif child.tag == 'nRows': nRows = (int)(child.text) elif child.tag == 'nCols': nCols = (int)(child.text) logging.info("upSpoke file: " + upFileName) logging.info("downSpoke file: " + downFileName) logging.info("crestSpoke file: " + crestFileName) reader = vtk.vtkXMLPolyDataReader() reader.SetFileName(upFileName) reader.Update() upSpokes = reader.GetOutput() upPointData = upSpokes.GetPointData() numberOfArrays = upPointData.GetNumberOfArrays() if numberOfArrays is 0: logging.warning("File: " + upFileName + " does not contain data") # medial_polyData = upSpokes # this is poly data for skeleton scene = slicer.mrmlScene # base line of medial sheet fidDisplayNode = slicer.vtkMRMLMarkupsDisplayNode() scene.AddNode(fidDisplayNode) fidNode = slicer.vtkMRMLMarkupsFiducialNode() # If we would have more than 100 fiducial points (meant for editing points) better to use a regular MRMLModelNode # In the future, we would like the user to be able to move the nodes, and the connected structures to update accordingly. # Meanwhile, we lock the moving. fidNode.SetLocked(True) fidDisplayNode.SetGlyphScale(0.01) fidDisplayNode.SetSelectedColor(1.0, 1.0, 0.0) fidDisplayNode.SetTextScale(0.0) scene.AddNode(fidNode) fidNode.SetAndObserveDisplayNodeID(fidDisplayNode.GetID()) # \TODO come up with better name later # prepare for arrows for upspokes upSpoke_points = vtk.vtkPoints() upSpoke_lines = vtk.vtkCellArray() arr_length = upPointData.GetArray('spokeLength') arr_dirs = upPointData.GetArray('spokeDirection') for i in range(upSpokes.GetNumberOfPoints()): pt = [0] * 3 upSpokes.GetPoint(i, pt) # base point of up arrows id0 = upSpoke_points.InsertNextPoint(pt) # head of up arrows spoke_length = arr_length.GetValue(i) baseIdx = i * 3 dirX = arr_dirs.GetValue(baseIdx) dirY = arr_dirs.GetValue(baseIdx + 1) dirZ = arr_dirs.GetValue(baseIdx + 2) pt1 = [0] * 3 pt1[0] = pt[0] + spoke_length * dirX pt1[1] = pt[1] + spoke_length * dirY pt1[2] = pt[2] + spoke_length * dirZ id1 = upSpoke_points.InsertNextPoint(pt1) up_arrow = vtk.vtkLine() up_arrow.GetPointIds().SetId(0, id0) up_arrow.GetPointIds().SetId(1, id1) upSpoke_lines.InsertNextCell(up_arrow) fidNode.AddFiducial(pt[0], pt[1], pt[2]) # boundary_point_ids = [] # model node for medial mesh medial_model = slicer.vtkMRMLModelNode() medial_model.SetScene(scene) medial_model.SetName("Medial Mesh") medial_model.SetAndObservePolyData(reader.GetOutput()) # model display node for the medial mesh medial_model_display = slicer.vtkMRMLModelDisplayNode() medial_model_display.SetColor(0, 0.5, 0) medial_model_display.SetScene(scene) medial_model_display.SetLineWidth(3.0) medial_model_display.SetRepresentation(1) medial_model_display.SetBackfaceCulling(0) scene.AddNode(medial_model_display) medial_model.SetAndObserveDisplayNodeID(medial_model_display.GetID()) scene.AddNode(medial_model) # model node for up spoke (poly data for arrows) upSpoke_polyData = vtk.vtkPolyData() upSpoke_polyData.SetPoints(upSpoke_points) upSpoke_polyData.SetLines(upSpoke_lines) upSpoke_model = slicer.vtkMRMLModelNode() upSpoke_model.SetScene(scene) upSpoke_model.SetName("Top Spoke") upSpoke_model.SetAndObservePolyData(upSpoke_polyData) # model display node for the top spoke # cyan for the top spoke upSpoke_model_display = slicer.vtkMRMLModelDisplayNode() upSpoke_model_display.SetColor(0, 1, 1) upSpoke_model_display.SetScene(scene) upSpoke_model_display.SetLineWidth(3.0) upSpoke_model_display.SetBackfaceCulling(0) scene.AddNode(upSpoke_model_display) upSpoke_model.SetAndObserveDisplayNodeID(upSpoke_model_display.GetID()) scene.AddNode(upSpoke_model) # prepare for down spokes reader.SetFileName(downFileName) reader.Update() downSpokes = reader.GetOutput() downSpoke_polyData = vtk.vtkPolyData() downSpoke_lines = vtk.vtkCellArray() downSpoke_points = vtk.vtkPoints() downPointData = downSpokes.GetPointData() arr_length = downPointData.GetArray('spokeLength') arr_dirs = downPointData.GetArray('spokeDirection') for i in range(downSpokes.GetNumberOfPoints()): # tail of arrows pt_tail = [0] * 3 downSpokes.GetPoint(i, pt_tail) id0 = downSpoke_points.InsertNextPoint(pt_tail) # head of arrows pt_head = [0] * 3 spoke_length = arr_length.GetValue(i) baseIdx = i * 3 dirX = arr_dirs.GetValue(baseIdx) dirY = arr_dirs.GetValue(baseIdx + 1) dirZ = arr_dirs.GetValue(baseIdx + 2) pt_head[0] = pt_tail[0] + spoke_length * dirX pt_head[1] = pt_tail[1] + spoke_length * dirY pt_head[2] = pt_tail[2] + spoke_length * dirZ id1 = downSpoke_points.InsertNextPoint(pt_head) # connection between head and tail con = vtk.vtkLine() con.GetPointIds().SetId(0, id0) con.GetPointIds().SetId(1, id1) downSpoke_lines.InsertNextCell(con) downSpoke_polyData.SetPoints(downSpoke_points) downSpoke_polyData.SetLines(downSpoke_lines) downSpoke_model = slicer.vtkMRMLModelNode() downSpoke_model.SetScene(scene) downSpoke_model.SetName("Bottom Spoke") downSpoke_model.SetAndObservePolyData(downSpoke_polyData) # model display node for the down spoke downSpoke_model_display = slicer.vtkMRMLModelDisplayNode() downSpoke_model_display.SetColor(1, 0, 1) downSpoke_model_display.SetScene(scene) downSpoke_model_display.SetLineWidth(3.0) downSpoke_model_display.SetBackfaceCulling(0) scene.AddNode(downSpoke_model_display) downSpoke_model.SetAndObserveDisplayNodeID( downSpoke_model_display.GetID()) scene.AddNode(downSpoke_model) # crest spoke new_reader = vtk.vtkXMLPolyDataReader() new_reader.SetFileName(crestFileName) new_reader.Update() foldCurve_polyData = new_reader.GetOutput() foldPointData = foldCurve_polyData.GetPointData() arr_length = foldPointData.GetArray('spokeLength') arr_dirs = foldPointData.GetArray('spokeDirection') crest_arrows_polydata = vtk.vtkPolyData() crest_arrows_points = vtk.vtkPoints() crest_arrows_lines = vtk.vtkCellArray() for i in range(foldCurve_polyData.GetNumberOfPoints()): # tail of crest arrows pt_tail = [0] * 3 foldCurve_polyData.GetPoint(i, pt_tail) id0 = crest_arrows_points.InsertNextPoint(pt_tail) # head of crest arrows pt_head = [0] * 3 spoke_length = arr_length.GetValue(i) baseIdx = i * 3 dirX = arr_dirs.GetValue(baseIdx) dirY = arr_dirs.GetValue(baseIdx + 1) dirZ = arr_dirs.GetValue(baseIdx + 2) pt_head[0] = pt_tail[0] + spoke_length * dirX pt_head[1] = pt_tail[1] + spoke_length * dirY pt_head[2] = pt_tail[2] + spoke_length * dirZ id1 = crest_arrows_points.InsertNextPoint(pt_head) crest_line = vtk.vtkLine() crest_line.GetPointIds().SetId(0, id0) crest_line.GetPointIds().SetId(1, id1) crest_arrows_lines.InsertNextCell(crest_line) crest_arrows_polydata.SetPoints(crest_arrows_points) crest_arrows_polydata.SetLines(crest_arrows_lines) # show crest arrows crestSpoke_model = slicer.vtkMRMLModelNode() crestSpoke_model.SetScene(scene) crestSpoke_model.SetName("Crest Spoke") crestSpoke_model.SetAndObservePolyData(crest_arrows_polydata) # model display node crestSpoke_model_display = slicer.vtkMRMLModelDisplayNode() crestSpoke_model_display.SetColor(1, 1, 0) crestSpoke_model_display.SetScene(scene) crestSpoke_model_display.SetLineWidth(3.0) crestSpoke_model_display.SetBackfaceCulling(0) scene.AddNode(crestSpoke_model_display) crestSpoke_model.SetAndObserveDisplayNodeID( crestSpoke_model_display.GetID()) scene.AddNode(crestSpoke_model) # show fold curve foldCurve_model = slicer.vtkMRMLModelNode() foldCurve_model.SetScene(scene) foldCurve_model.SetName("Fold Curve") foldCurve_model.SetAndObservePolyData(foldCurve_polyData) # model display node foldCurve_model_display = slicer.vtkMRMLModelDisplayNode() foldCurve_model_display.SetColor(1, 1, 0) foldCurve_model_display.SetScene(scene) foldCurve_model_display.SetLineWidth(3.0) foldCurve_model_display.SetBackfaceCulling(0) scene.AddNode(foldCurve_model_display) foldCurve_model.SetAndObserveDisplayNodeID( foldCurve_model_display.GetID()) scene.AddNode(foldCurve_model) # show connections to fold curve point from nearby interior points # compute the nearest interior point connection_polydata = vtk.vtkPolyData() connection_points = vtk.vtkPoints() connection_lines = vtk.vtkCellArray() for i in range(foldCurve_polyData.GetNumberOfPoints()): min_dist = 100000.0 nearest_index = 0 pt_fold = [0] * 3 foldCurve_polyData.GetPoint(i, pt_fold) id0 = connection_points.InsertNextPoint(pt_fold) for j in range(upSpokes.GetNumberOfPoints()): pt_interior = [0] * 3 upSpokes.GetPoint(j, pt_interior) dist = self.distance(pt_fold, pt_interior) if dist < min_dist: min_dist = dist nearest_index = j pt_nearest_interior = upSpokes.GetPoint(nearest_index) id1 = connection_points.InsertNextPoint(pt_nearest_interior) line = vtk.vtkLine() line.GetPointIds().SetId(0, id0) line.GetPointIds().SetId(1, id1) connection_lines.InsertNextCell(line) connection_polydata.SetPoints(connection_points) connection_polydata.SetLines(connection_lines) connection_model = slicer.vtkMRMLModelNode() connection_model.SetScene(scene) connection_model.SetName("Connection to Fold Curve") connection_model.SetAndObservePolyData(connection_polydata) # model display node connection_model_display = slicer.vtkMRMLModelDisplayNode() connection_model_display.SetColor(0, 0, 0) connection_model_display.SetScene(scene) connection_model_display.SetLineWidth(3.0) connection_model_display.SetBackfaceCulling(0) scene.AddNode(connection_model_display) connection_model.SetAndObserveDisplayNodeID( connection_model_display.GetID()) scene.AddNode(connection_model)
def run(self, enableScreenshots=0, screenshotScaleFactor=1): """ Run the actual algorithm """ self.delayDisplay( 'Running test of the Neurosurgical Planning tutorial') self.enableScreenshots = enableScreenshots self.screenshotScaleFactor = screenshotScaleFactor # conventional layout lm = slicer.app.layoutManager() lm.setLayout(2) moduleSelector = slicer.util.mainWindow().moduleSelector() # # first load the data # if self.enableScreenshots == 1: # for the tutorial, do it through the welcome module moduleSelector.selectModule('Welcome') self.delayDisplay("Screenshot") self.takeScreenshot('NeurosurgicalPlanning-Welcome', 'Welcome module', -1) else: # otherwise show the sample data module moduleSelector.selectModule('SampleData') # use the sample data module logic to load data for the self test import SampleData sampleDataLogic = SampleData.SampleDataLogic() self.delayDisplay("Getting Baseline volume") baselineVolume = sampleDataLogic.downloadWhiteMatterExplorationBaselineVolume( ) self.delayDisplay("Getting DTI volume") dtiVolume = sampleDataLogic.downloadWhiteMatterExplorationDTIVolume() self.takeScreenshot('NeurosurgicalPlanning-Loaded', 'Data loaded', -1) # # link the viewers # if self.enableScreenshots == 1: # for the tutorial, pop up the linking control sliceController = slicer.app.layoutManager().sliceWidget( "Red").sliceController() popupWidget = sliceController.findChild("ctkPopupWidget") if popupWidget != None: popupWidget.pinPopup(1) self.takeScreenshot('NeurosurgicalPlanning-Link', 'Link slice viewers', -1) popupWidget.pinPopup(0) sliceLogic = slicer.app.layoutManager().sliceWidget('Red').sliceLogic() compositeNode = sliceLogic.GetSliceCompositeNode() compositeNode.SetLinkedControl(1) # # baseline in the background # sliceLogic.StartSliceCompositeNodeInteraction(1) compositeNode.SetBackgroundVolumeID(baselineVolume.GetID()) sliceLogic.EndSliceCompositeNodeInteraction() self.takeScreenshot('NeurosurgicalPlanning-Baseline', 'Baseline in background', -1) # # adjust window level on baseline # moduleSelector.selectModule('Volumes') baselineDisplay = baselineVolume.GetDisplayNode() baselineDisplay.SetAutoWindowLevel(0) baselineDisplay.SetWindow(2600) baselineDisplay.SetLevel(1206) self.takeScreenshot('NeurosurgicalPlanning-WindowLevel', 'Set W/L on baseline', -1) # # switch to red slice only # lm.setLayout(6) self.takeScreenshot('NeurosurgicalPlanning-RedSliceOnly', 'Set layout to Red Slice only', -1) # # segmentation of tumour # # # create a label map and set it for editing # volumesLogic = slicer.modules.volumes.logic() baselineVolumeLabel = volumesLogic.CreateAndAddLabelVolume( slicer.mrmlScene, baselineVolume, baselineVolume.GetName() + '-label') baselineDisplayNode = baselineVolumeLabel.GetDisplayNode() baselineDisplayNode.SetAndObserveColorNodeID( 'vtkMRMLColorTableNodeFileGenericAnatomyColors.txt') selectionNode = slicer.app.applicationLogic().GetSelectionNode() selectionNode.SetReferenceActiveVolumeID(baselineVolume.GetID()) selectionNode.SetReferenceActiveLabelVolumeID( baselineVolumeLabel.GetID()) slicer.app.applicationLogic().PropagateVolumeSelection(0) # # editor module # moduleSelector.selectModule('Editor') self.takeScreenshot('NeurosurgicalPlanning-Editor', 'Showing Editor Module', -1) # set the slice offset so drawing is right sliceNode = sliceLogic.GetSliceNode() sliceOffset = 58.7 sliceNode.SetSliceOffset(sliceOffset) # # paint # parameterNode = EditUtil.getParameterNode() paintEffect = EditorLib.PaintEffectOptions() paintEffect.setMRMLDefaults() paintEffect.__del__() sliceWidget = lm.sliceWidget('Red') paintTool = EditorLib.PaintEffectTool(sliceWidget) self.takeScreenshot('NeurosurgicalPlanning-Paint', 'Paint tool in Editor Module', -1) # # paint in cystic part of tumor, using converstion from RAS coords to # avoid slice widget size differences # EditUtil.setLabel(293) displayCoords = self.rasToDisplay(-7.4, 71, sliceOffset) paintTool.paintAddPoint(displayCoords[0], displayCoords[1]) displayCoords = self.rasToDisplay(-11, 73, sliceOffset) paintTool.paintAddPoint(displayCoords[0], displayCoords[1]) displayCoords = self.rasToDisplay(-12, 85, sliceOffset) paintTool.paintAddPoint(displayCoords[0], displayCoords[1]) displayCoords = self.rasToDisplay(-13, 91, sliceOffset) paintTool.paintAddPoint(displayCoords[0], displayCoords[1]) displayCoords = self.rasToDisplay(-15, 78, sliceOffset) paintTool.paintAddPoint(displayCoords[0], displayCoords[1]) paintTool.paintApply() self.takeScreenshot('NeurosurgicalPlanning-PaintCystic', 'Paint cystic part of tumor', -1) # # paint in solid part of tumor # EditUtil.setLabel(7) displayCoords = self.rasToDisplay(-0.5, 118.5, sliceOffset) paintTool.paintAddPoint(displayCoords[0], displayCoords[1]) displayCoords = self.rasToDisplay(-7.4, 116, sliceOffset) paintTool.paintAddPoint(displayCoords[0], displayCoords[1]) paintTool.paintApply() self.takeScreenshot('NeurosurgicalPlanning-PaintSolid', 'Paint solid part of tumor', -1) # # paint around the tumor # EditUtil.setLabel(295) rMax = 25 rMin = -50 aMax = 145 aMin = 50 rasStep = 5 # draw the top and bottom for r in range(rMin, rMax, rasStep): displayCoords = self.rasToDisplay(r, aMin, sliceOffset) paintTool.paintAddPoint(displayCoords[0], displayCoords[1]) displayCoords = self.rasToDisplay(r, aMax, sliceOffset) paintTool.paintAddPoint(displayCoords[0], displayCoords[1]) # draw the left and right for a in range(aMin, aMax, rasStep): displayCoords = self.rasToDisplay(rMin, a, sliceOffset) paintTool.paintAddPoint(displayCoords[0], displayCoords[1]) displayCoords = self.rasToDisplay(rMax, a, sliceOffset) paintTool.paintAddPoint(displayCoords[0], displayCoords[1]) paintTool.paintApply() self.takeScreenshot('NeurosurgicalPlanning-PaintAround', 'Paint around tumor', -1) # # clean up after painting # paintTool.cleanup() paintTool = None # # Grow cut # growCutLogic = EditorLib.GrowCutEffectLogic(sliceWidget.sliceLogic()) growCutLogic.growCut() self.takeScreenshot('NeurosurgicalPlanning-Growcut', 'Growcut', -1) # # Merge split volume # slicer.util.selectModule('Editor') slicer.util.findChildren(text='Split Merge Volume')[0].clicked() self.takeScreenshot('NeurosurgicalPlanning-SplitMerge', 'SplitMerge', -1) # # go to the data module # moduleSelector.selectModule('Data') self.takeScreenshot('NeurosurgicalPlanning-SplitMergeData', 'SplitMerge results in Data', -1) # # Ventricles Segmentation # moduleSelector.selectModule('Editor') # # select the label volume with the area around the tumor slicer.util.findChildren( name='PerStructureVolumesFrame')[0].collapsed = False treeView = slicer.util.findChildren(name='StructuresView')[0] selection = qt.QItemSelection() # selecting the last split volume in the third row row = 2 rowStart = treeView.model().index(row, 0) rowEnd = treeView.model().index(row, treeView.model().columnCount() - 1) # rowSel = qt.QItemSelection(rowStart, rowEnd) selection.select(rowStart, rowEnd) # backup: select the label map in the slice logic too baselinelabel295 = slicer.mrmlScene.GetFirstNodeByName( "BaselineVolume-region 3-label") sliceLogic.StartSliceCompositeNodeInteraction(1) compositeNode.SetLabelVolumeID(baselinelabel295.GetID()) sliceLogic.EndSliceCompositeNodeInteraction() self.takeScreenshot('NeurosurgicalPlanning-SelOutside', 'Select outside region', -1) # # Threshold tool # slicer.modules.EditorWidget.toolsBox.selectEffect('ThresholdEffect') parameterNode = EditUtil.getParameterNode() parameterNode.SetParameter('ThresholdEffect,min', str(1700)) slicer.modules.EditorWidget.toolsBox.currentTools[0].apply() self.takeScreenshot('NeurosurgicalPlanning-Ventricles', 'Ventricles segmentation', -1) # # Save Islands # slicer.modules.EditorWidget.toolsBox.selectEffect('SaveIslandEffect') saveIslandLogic = EditorLib.SaveIslandEffectLogic( sliceWidget.sliceLogic()) displayCoords = self.rasToDisplay(25.3, 5.8, sliceOffset) xy = (displayCoords[0], displayCoords[1]) saveIslandLogic.saveIsland(xy) self.takeScreenshot('NeurosurgicalPlanning-SaveIsland', 'Ventricles save island', -1) # # Merge and build # slicer.util.findChildren(text='Merge And Build')[0].clicked() # # switch to conventional layout # lm.setLayout(2) self.takeScreenshot('NeurosurgicalPlanning-MergeAndBuild', 'Merged and built models', -1) # # Tractography label map seeding # # # select label volume with label 293, in the second row # row = 1 rowStart = treeView.model().index(row, 0) rowEnd = treeView.model().index(row, treeView.model().columnCount() - 1) # rowSel = qt.QItemSelection(rowStart, rowEnd) selection.select(rowStart, rowEnd) # backup: select the label map in the slice logic too baselinelabel293 = slicer.mrmlScene.GetFirstNodeByName( "BaselineVolume-region 1-label") sliceLogic.StartSliceCompositeNodeInteraction(1) compositeNode.SetLabelVolumeID(baselinelabel293.GetID()) sliceLogic.EndSliceCompositeNodeInteraction() self.takeScreenshot('NeurosurgicalPlanning-SelCystic', 'Select cystic region', -1) # # Dilate # slicer.modules.EditorWidget.toolsBox.selectEffect('DilateEffect') EditUtil.setLabel(293) self.takeScreenshot('NeurosurgicalPlanning-Dilate', 'Dilate tool', -1) # tutorial says to click apply three times for d in range(1, 3): print d # slicer.util.findChildren(name='DilateEffectOptionsApply')[0].clicked() # slicer.modules.EditorWidget.toolsBox.currentTools[0].apply() slicer.modules.EditorWidget.toolsBox.currentOption.onApply() self.takeScreenshot('NeurosurgicalPlanning-Dilated', 'Dilated tumor', -1) # # Tractography Label Map Seeding module # moduleSelector.selectModule('TractographyLabelMapSeeding') self.takeScreenshot('NeurosurgicalPlanning-LabelMapSeedingModule', 'Showing Tractography Label Seeding Module', -1) tractographyLabelSeeding = slicer.modules.tractographylabelmapseeding parameters = {} parameters['InputVolume'] = dtiVolume.GetID() baselinelabel293 = slicer.mrmlScene.GetFirstNodeByName( "BaselineVolume-region 1-label") # VTK6 TODO - set 'InputROIPipelineInfo' parameters['InputROI'] = baselinelabel293.GetID() fibers = slicer.vtkMRMLFiberBundleNode() slicer.mrmlScene.AddNode(fibers) parameters['OutputFibers'] = fibers.GetID() parameters['UseIndexSpace'] = 1 parameters['StoppingValue'] = 0.15 parameters['ROIlabel'] = 293 parameters['StoppingMode'] = 'FractionalAnisotropy' # defaults # parameters['ClTh'] = 0.3 # parameters['MinimumLength'] = 20 # parameters['MaximumLength'] = 800 # parameters['StoppingCurvature'] = 0.7 # parameters['IntegrationStepLength'] = 0.5 # parameters['SeedSpacing'] = 2 # and run it slicer.cli.run(tractographyLabelSeeding, None, parameters) self.takeScreenshot('NeurosurgicalPlanning-LabelMapSeeding', 'Showing Tractography Label Seeding Results', -1) # # tractography fiducial seeding # moduleSelector.selectModule('TractographyInteractiveSeeding') self.takeScreenshot('NeurosurgicalPlanning-TIS', 'Showing Tractography Interactive Seeding Module', -1) # DTI in background sliceLogic.StartSliceCompositeNodeInteraction(1) compositeNode.SetBackgroundVolumeID(dtiVolume.GetID()) sliceLogic.EndSliceCompositeNodeInteraction() # DTI visible in 3D sliceNode = sliceLogic.GetSliceNode() sliceLogic.StartSliceNodeInteraction(128) sliceNode.SetSliceVisible(1) sliceLogic.EndSliceNodeInteraction() self.takeScreenshot( 'NeurosurgicalPlanning-TIS-DTI', 'DTI volume with Tractography Interactive Seeding Module', -1) # place a fiducial displayNode = slicer.vtkMRMLMarkupsDisplayNode() slicer.mrmlScene.AddNode(displayNode) fidNode = slicer.vtkMRMLMarkupsFiducialNode() fidNode.SetName('F') slicer.mrmlScene.AddNode(fidNode) fidNode.SetAndObserveDisplayNodeID(displayNode.GetID()) r = 28.338526 a = 34.064367 s = sliceOffset fidNode.AddFiducial(r, a, s) # make it active selectionNode = slicer.mrmlScene.GetNodeByID( "vtkMRMLSelectionNodeSingleton") if (selectionNode != None): selectionNode.SetReferenceActivePlaceNodeID(fidNode.GetID()) self.takeScreenshot( 'NeurosurgicalPlanning-TIS-Fid1', 'Fiducial in Tractography Interactive Seeding Module', -1) # set up the arguments wr = slicer.modules.tractographyinteractiveseeding.widgetRepresentation( ) wr.setDiffusionTensorVolumeNode(dtiVolume) # create a fiber bundle fiducialFibers = slicer.vtkMRMLFiberBundleNode() slicer.mrmlScene.AddNode(fiducialFibers) wr.setFiberBundleNode(fiducialFibers) wr.setSeedingNode(fidNode) wr.setMinimumPath(10) wr.setStoppingValue(0.15) self.takeScreenshot('NeurosurgicalPlanning-TIS-Args', 'Tractography Interactive Seeding arguments', -1) self.delayDisplay("Moving the fiducial") for y in range(-20, 100, 5): msg = "Moving the fiducial to y = " + str(y) self.delayDisplay(msg, 250) fidNode.SetNthFiducialPosition(0, r, y, s) self.takeScreenshot( 'NeurosurgicalPlanning-TIS-Moved', 'Moved fiducial and did Tractography Interactive Seeding', -1) return True
def run(self, enableScreenshots=0, screenshotScaleFactor=1): """ Run the actual algorithm """ self.delayDisplay("Running test of the Neurosurgical Planning tutorial") self.enableScreenshots = enableScreenshots self.screenshotScaleFactor = screenshotScaleFactor # conventional layout lm = slicer.app.layoutManager() lm.setLayout(2) moduleSelector = slicer.util.mainWindow().moduleSelector() # # first load the data # if self.enableScreenshots == 1: # for the tutorial, do it through the welcome module moduleSelector.selectModule("Welcome") self.delayDisplay("Screenshot") self.takeScreenshot("NeurosurgicalPlanning-Welcome", "Welcome module", -1) else: # otherwise show the sample data module moduleSelector.selectModule("SampleData") # use the sample data module logic to load data for the self test import SampleData sampleDataLogic = SampleData.SampleDataLogic() self.delayDisplay("Getting Baseline volume") baselineVolume = sampleDataLogic.downloadWhiteMatterExplorationBaselineVolume() self.delayDisplay("Getting DTI volume") dtiVolume = sampleDataLogic.downloadWhiteMatterExplorationDTIVolume() self.takeScreenshot("NeurosurgicalPlanning-Loaded", "Data loaded", -1) # # create a label map and set it for editing # volumesLogic = slicer.modules.volumes.logic() baselineVolumeLabel = volumesLogic.CreateAndAddLabelVolume( slicer.mrmlScene, baselineVolume, baselineVolume.GetName() + "-label" ) baselineDisplayNode = baselineVolumeLabel.GetDisplayNode() baselineDisplayNode.SetAndObserveColorNodeID("vtkMRMLColorTableNodeFileGenericAnatomyColors.txt") selectionNode = slicer.app.applicationLogic().GetSelectionNode() selectionNode.SetReferenceActiveVolumeID(baselineVolume.GetID()) selectionNode.SetReferenceActiveLabelVolumeID(baselineVolumeLabel.GetID()) slicer.app.applicationLogic().PropagateVolumeSelection(0) data = slicer.util.array(baselineVolume.GetName() + "-label") data[6:15, 110:140, 130:160] = 293 # # link the viewers # if self.enableScreenshots == 1: # for the tutorial, pop up the linking control sliceController = slicer.app.layoutManager().sliceWidget("Red").sliceController() popupWidget = sliceController.findChild("ctkPopupWidget") if popupWidget is not None: popupWidget.pinPopup(1) self.takeScreenshot("NeurosurgicalPlanning-Link", "Link slice viewers", -1) popupWidget.pinPopup(0) # # Tractography Label Map Seeding module # moduleSelector.selectModule("TractographyLabelMapSeeding") self.takeScreenshot( "NeurosurgicalPlanning-LabelMapSeedingModule", "Showing Tractography Label Seeding Module", -1 ) tractographyLabelSeeding = slicer.modules.tractographylabelmapseeding parameters = {} parameters["InputVolume"] = dtiVolume.GetID() baselinelabel293 = slicer.mrmlScene.GetFirstNodeByName("BaselineVolume-label") # VTK6 TODO - set 'InputROIPipelineInfo' parameters["InputROI"] = baselinelabel293.GetID() fibers = slicer.vtkMRMLFiberBundleNode() slicer.mrmlScene.AddNode(fibers) parameters["OutputFibers"] = fibers.GetID() parameters["UseIndexSpace"] = 1 parameters["StoppingValue"] = 0.15 parameters["ROIlabel"] = 293 parameters["ThresholdMode"] = "FractionalAnisotropy" # defaults # parameters['ClTh'] = 0.3 # parameters['MinimumLength'] = 20 # parameters['MaximumLength'] = 800 # parameters['StoppingCurvature'] = 0.7 # parameters['IntegrationStepLength'] = 0.5 # parameters['SeedSpacing'] = 2 # and run it slicer.cli.run(tractographyLabelSeeding, None, parameters) self.takeScreenshot("NeurosurgicalPlanning-LabelMapSeeding", "Showing Tractography Label Seeding Results", -1) # # tractography fiducial seeding # moduleSelector.selectModule("TractographyInteractiveSeeding") self.takeScreenshot("NeurosurgicalPlanning-TIS", "Showing Tractography Interactive Seeding Module", -1) # DTI in background sliceLogic = slicer.app.layoutManager().sliceWidget("Red").sliceLogic() sliceLogic.StartSliceCompositeNodeInteraction(1) compositeNode = sliceLogic.GetSliceCompositeNode() compositeNode.SetBackgroundVolumeID(dtiVolume.GetID()) sliceLogic.EndSliceCompositeNodeInteraction() # DTI visible in 3D sliceNode = sliceLogic.GetSliceNode() sliceLogic.StartSliceNodeInteraction(128) sliceNode.SetSliceVisible(1) sliceLogic.EndSliceNodeInteraction() self.takeScreenshot( "NeurosurgicalPlanning-TIS-DTI", "DTI volume with Tractography Interactive Seeding Module", -1 ) # place a fiducial displayNode = slicer.vtkMRMLMarkupsDisplayNode() slicer.mrmlScene.AddNode(displayNode) fidNode = slicer.vtkMRMLMarkupsFiducialNode() fidNode.SetName("F") slicer.mrmlScene.AddNode(fidNode) fidNode.SetAndObserveDisplayNodeID(displayNode.GetID()) r = 28.338526 a = 34.064367 sliceOffset = 58.7 s = sliceOffset fidNode.AddFiducial(r, a, s) # make it active selectionNode = slicer.mrmlScene.GetNodeByID("vtkMRMLSelectionNodeSingleton") if selectionNode is not None: selectionNode.SetReferenceActivePlaceNodeID(fidNode.GetID()) self.takeScreenshot("NeurosurgicalPlanning-TIS-Fid1", "Fiducial in Tractography Interactive Seeding Module", -1) # set up the arguments wr = slicer.modules.tractographyinteractiveseeding.widgetRepresentation() wr.setDiffusionTensorVolumeNode(dtiVolume) # create a fiber bundle fiducialFibers = slicer.vtkMRMLFiberBundleNode() slicer.mrmlScene.AddNode(fiducialFibers) wr.setFiberBundleNode(fiducialFibers) wr.setSeedingNode(fidNode) wr.setMinimumPath(10) wr.setStoppingValue(0.15) self.takeScreenshot("NeurosurgicalPlanning-TIS-Args", "Tractography Interactive Seeding arguments", -1) self.delayDisplay("Moving the fiducial") for y in range(-20, 100, 5): msg = "Moving the fiducial to y = " + str(y) self.delayDisplay(msg, 250) fidNode.SetNthFiducialPosition(0, r, y, s) self.takeScreenshot( "NeurosurgicalPlanning-TIS-Moved", "Moved fiducial and did Tractography Interactive Seeding", -1 ) return True
def run(self): """ Run the actual algorithm """ print('Running test of the markups in compare viewers') # # first load the data # print("Getting MR Head Volume") import SampleData mrHeadVolume = SampleData.downloadSample("MRHead") # # link the viewers # sliceLogic = slicer.app.layoutManager().sliceWidget('Red').sliceLogic() compositeNode = sliceLogic.GetSliceCompositeNode() compositeNode.SetLinkedControl(1) # # MR Head in the background # sliceLogic.StartSliceCompositeNodeInteraction(1) compositeNode.SetBackgroundVolumeID(mrHeadVolume.GetID()) sliceLogic.EndSliceCompositeNodeInteraction() # # switch to conventional layout # lm = slicer.app.layoutManager() lm.setLayout(2) # create a fiducial list displayNode = slicer.vtkMRMLMarkupsDisplayNode() slicer.mrmlScene.AddNode(displayNode) fidNode = slicer.vtkMRMLMarkupsFiducialNode() slicer.mrmlScene.AddNode(fidNode) fidNode.SetAndObserveDisplayNodeID(displayNode.GetID()) # make it active selectionNode = slicer.mrmlScene.GetNodeByID("vtkMRMLSelectionNodeSingleton") if (selectionNode is not None): selectionNode.SetReferenceActivePlaceNodeID(fidNode.GetID()) # add some known points to it eye1 = [33.4975, 79.4042, -10.2143] eye2 = [-31.283, 80.9652, -16.2143] nose = [4.61944, 114.526, -33.2143] index = fidNode.AddFiducialFromArray(eye1) fidNode.SetNthFiducialLabel(index, "eye-1") index = fidNode.AddFiducialFromArray(eye2) fidNode.SetNthFiducialLabel(index, "eye-2") index = fidNode.AddFiducialFromArray(nose) fidNode.SetNthFiducialLabel(index, "nose") self.delayDisplay("Placed 3 fiducials") # # switch to 2 viewers compare layout # lm.setLayout(12) self.delayDisplay("Switched to Compare 2 viewers") # # get compare slice composite node # compareLogic1 = slicer.app.layoutManager().sliceWidget('Compare1').sliceLogic() compareCompositeNode1 = compareLogic1.GetSliceCompositeNode() # set MRHead in the background compareLogic1.StartSliceCompositeNodeInteraction(1) compareCompositeNode1.SetBackgroundVolumeID(mrHeadVolume.GetID()) compareLogic1.EndSliceCompositeNodeInteraction() compareLogic1.FitSliceToAll() # make it visible in 3D compareLogic1.GetSliceNode().SetSliceVisible(1) # scroll to a fiducial location compareLogic1.StartSliceOffsetInteraction() compareLogic1.SetSliceOffset(eye1[2]) compareLogic1.EndSliceOffsetInteraction() self.delayDisplay("MH Head in background, scrolled to a fiducial") # scroll around through the range of points offset = nose[2] while offset < eye1[2]: compareLogic1.StartSliceOffsetInteraction() compareLogic1.SetSliceOffset(offset) compareLogic1.EndSliceOffsetInteraction() msg = "Scrolled to " + str(offset) self.delayDisplay(msg,250) offset += 1.0 # switch back to conventional lm.setLayout(2) self.delayDisplay("Switched back to conventional layout") # switch to compare grid lm.setLayout(23) compareLogic1.FitSliceToAll() self.delayDisplay("Switched to Compare grid") # switch back to conventional lm.setLayout(2) self.delayDisplay("Switched back to conventional layout") return True
def visualizeNewSrep(self, filename): # 1. parse header file tree = ET.parse(filename) upFileName = '' crestFileName = '' downFileName = '' nCols = 0 nRows = 0 for child in tree.getroot(): if child.tag == 'upSpoke': upFileName = child.text elif child.tag == 'downSpoke': downFileName = child.text elif child.tag == 'crestSpoke': crestFileName = child.text elif child.tag == 'nRows': nRows = (int)(child.text) elif child.tag == 'nCols': nCols = (int)(child.text) reader = vtk.vtkXMLPolyDataReader() reader.SetFileName(upFileName) reader.Update() upSpokes = reader.GetOutput() upPointData = upSpokes.GetPointData() medial_polyData = upSpokes # this is poly data for skeleton scene = slicer.mrmlScene # base line of medial sheet fidDisplayNode = slicer.vtkMRMLMarkupsDisplayNode() scene.AddNode(fidDisplayNode) fidNode = slicer.vtkMRMLMarkupsFiducialNode() fidDisplayNode.SetGlyphScale(0.01) fidDisplayNode.SetSelectedColor(1.0, 1.0, 0.0) fidDisplayNode.SetTextScale(0.0) scene.AddNode(fidNode) fidNode.SetAndObserveDisplayNodeID(fidDisplayNode.GetID()) # \TODO come up with better name later # prepare for arrows for upspokes upSpoke_points = vtk.vtkPoints() upSpoke_lines = vtk.vtkCellArray() arr_length = upPointData.GetArray('spokeLength') arr_dirs = upPointData.GetArray('spokeDirection') for i in range(upSpokes.GetNumberOfPoints()): pt = [0] * 3 upSpokes.GetPoint(i, pt) # base point of up arrows id0 = upSpoke_points.InsertNextPoint(pt) # head of up arrows spoke_length = arr_length.GetValue(i) baseIdx = i * 3 dirX = arr_dirs.GetValue(baseIdx) dirY = arr_dirs.GetValue(baseIdx + 1) dirZ = arr_dirs.GetValue(baseIdx + 2) pt1 = [0] * 3 pt1[0] = pt[0] + spoke_length * dirX pt1[1] = pt[1] + spoke_length * dirY pt1[2] = pt[2] + spoke_length * dirZ id1 = upSpoke_points.InsertNextPoint(pt1) up_arrow = vtk.vtkLine() up_arrow.GetPointIds().SetId(0, id0) up_arrow.GetPointIds().SetId(1, id1) upSpoke_lines.InsertNextCell(up_arrow) fidNode.AddFiducial(pt[0], pt[1], pt[2]) boundary_point_ids = [] # model node for medial mesh medial_model = slicer.vtkMRMLModelNode() medial_model.SetScene(scene) medial_model.SetName("Medial Mesh") medial_model.SetAndObservePolyData(reader.GetOutput()) # model display node for the medial mesh medial_model_display = slicer.vtkMRMLModelDisplayNode() medial_model_display.SetColor(0, 0.5, 0) medial_model_display.SetScene(scene) medial_model_display.SetLineWidth(3.0) medial_model_display.SetRepresentation(1) medial_model_display.SetBackfaceCulling(0) scene.AddNode(medial_model_display) medial_model.SetAndObserveDisplayNodeID(medial_model_display.GetID()) scene.AddNode(medial_model) # model node for up spoke (poly data for arrows) upSpoke_polyData = vtk.vtkPolyData() upSpoke_polyData.SetPoints(upSpoke_points) upSpoke_polyData.SetLines(upSpoke_lines) upSpoke_model = slicer.vtkMRMLModelNode() upSpoke_model.SetScene(scene) upSpoke_model.SetName("Top Spoke") upSpoke_model.SetAndObservePolyData(upSpoke_polyData) # model display node for the top spoke # cyan for the top spoke upSpoke_model_display = slicer.vtkMRMLModelDisplayNode() upSpoke_model_display.SetColor(0, 1, 1) upSpoke_model_display.SetScene(scene) upSpoke_model_display.SetLineWidth(3.0) upSpoke_model_display.SetBackfaceCulling(0) scene.AddNode(upSpoke_model_display) upSpoke_model.SetAndObserveDisplayNodeID(upSpoke_model_display.GetID()) scene.AddNode(upSpoke_model) # prepare for down spokes reader.SetFileName(downFileName) reader.Update() downSpokes = reader.GetOutput() downSpoke_polyData = vtk.vtkPolyData() downSpoke_lines = vtk.vtkCellArray() downSpoke_points = vtk.vtkPoints() downPointData = downSpokes.GetPointData() arr_length = downPointData.GetArray('spokeLength') arr_dirs = downPointData.GetArray('spokeDirection') for i in range(downSpokes.GetNumberOfPoints()): # tail of arrows pt_tail = [0] * 3 downSpokes.GetPoint(i, pt_tail) id0 = downSpoke_points.InsertNextPoint(pt_tail) # head of arrows pt_head = [0] * 3 spoke_length = arr_length.GetValue(i) baseIdx = i * 3 dirX = arr_dirs.GetValue(baseIdx) dirY = arr_dirs.GetValue(baseIdx + 1) dirZ = arr_dirs.GetValue(baseIdx + 2) pt_head[0] = pt_tail[0] + spoke_length * dirX pt_head[1] = pt_tail[1] + spoke_length * dirY pt_head[2] = pt_tail[2] + spoke_length * dirZ id1 = downSpoke_points.InsertNextPoint(pt_head) # connection between head and tail con = vtk.vtkLine() con.GetPointIds().SetId(0, id0) con.GetPointIds().SetId(1, id1) downSpoke_lines.InsertNextCell(con) downSpoke_polyData.SetPoints(downSpoke_points) downSpoke_polyData.SetLines(downSpoke_lines) downSpoke_model = slicer.vtkMRMLModelNode() downSpoke_model.SetScene(scene) downSpoke_model.SetName("Bottom Spoke") downSpoke_model.SetAndObservePolyData(downSpoke_polyData) # model display node for the down spoke downSpoke_model_display = slicer.vtkMRMLModelDisplayNode() downSpoke_model_display.SetColor(1, 0, 1) downSpoke_model_display.SetScene(scene) downSpoke_model_display.SetLineWidth(3.0) downSpoke_model_display.SetBackfaceCulling(0) scene.AddNode(downSpoke_model_display) downSpoke_model.SetAndObserveDisplayNodeID( downSpoke_model_display.GetID()) scene.AddNode(downSpoke_model) # crest spoke new_reader = vtk.vtkXMLPolyDataReader() new_reader.SetFileName(crestFileName) new_reader.Update() foldCurve_polyData = new_reader.GetOutput() foldPointData = foldCurve_polyData.GetPointData() arr_length = foldPointData.GetArray('spokeLength') arr_dirs = foldPointData.GetArray('spokeDirection') crest_arrows_polydata = vtk.vtkPolyData() crest_arrows_points = vtk.vtkPoints() crest_arrows_lines = vtk.vtkCellArray() for i in range(foldCurve_polyData.GetNumberOfPoints()): # tail of crest arrows pt_tail = [0] * 3 foldCurve_polyData.GetPoint(i, pt_tail) id0 = crest_arrows_points.InsertNextPoint(pt_tail) # head of crest arrows pt_head = [0] * 3 spoke_length = arr_length.GetValue(i) baseIdx = i * 3 dirX = arr_dirs.GetValue(baseIdx) dirY = arr_dirs.GetValue(baseIdx + 1) dirZ = arr_dirs.GetValue(baseIdx + 2) pt_head[0] = pt_tail[0] + spoke_length * dirX pt_head[1] = pt_tail[1] + spoke_length * dirY pt_head[2] = pt_tail[2] + spoke_length * dirZ id1 = crest_arrows_points.InsertNextPoint(pt_head) crest_line = vtk.vtkLine() crest_line.GetPointIds().SetId(0, id0) crest_line.GetPointIds().SetId(1, id1) crest_arrows_lines.InsertNextCell(crest_line) crest_arrows_polydata.SetPoints(crest_arrows_points) crest_arrows_polydata.SetLines(crest_arrows_lines) # show crest arrows crestSpoke_model = slicer.vtkMRMLModelNode() crestSpoke_model.SetScene(scene) crestSpoke_model.SetName("Crest Spoke") crestSpoke_model.SetAndObservePolyData(crest_arrows_polydata) # model display node crestSpoke_model_display = slicer.vtkMRMLModelDisplayNode() crestSpoke_model_display.SetColor(1, 1, 0) crestSpoke_model_display.SetScene(scene) crestSpoke_model_display.SetLineWidth(3.0) crestSpoke_model_display.SetBackfaceCulling(0) scene.AddNode(crestSpoke_model_display) crestSpoke_model.SetAndObserveDisplayNodeID( crestSpoke_model_display.GetID()) scene.AddNode(crestSpoke_model) # show fold curve foldCurve_model = slicer.vtkMRMLModelNode() foldCurve_model.SetScene(scene) foldCurve_model.SetName("Fold Curve") foldCurve_model.SetAndObservePolyData(foldCurve_polyData) # model display node foldCurve_model_display = slicer.vtkMRMLModelDisplayNode() foldCurve_model_display.SetColor(1, 1, 0) foldCurve_model_display.SetScene(scene) foldCurve_model_display.SetLineWidth(3.0) foldCurve_model_display.SetBackfaceCulling(0) scene.AddNode(foldCurve_model_display) foldCurve_model.SetAndObserveDisplayNodeID( foldCurve_model_display.GetID()) scene.AddNode(foldCurve_model) # show connections to fold curve point from nearby interior points # compute the nearest interior point connection_polydata = vtk.vtkPolyData() connection_points = vtk.vtkPoints() connection_lines = vtk.vtkCellArray() for i in range(foldCurve_polyData.GetNumberOfPoints()): min_dist = 100000.0 nearest_index = 0 pt_fold = [0] * 3 foldCurve_polyData.GetPoint(i, pt_fold) id0 = connection_points.InsertNextPoint(pt_fold) for j in range(upSpokes.GetNumberOfPoints()): pt_interior = [0] * 3 upSpokes.GetPoint(j, pt_interior) dist = math.sqrt((pt_fold[0] - pt_interior[0])**2 + (pt_fold[1] - pt_interior[1])**2 + (pt_fold[2] - pt_interior[2])**2) if dist < min_dist: min_dist = dist nearest_index = j pt_nearest_interior = upSpokes.GetPoint(nearest_index) id1 = connection_points.InsertNextPoint(pt_nearest_interior) line = vtk.vtkLine() line.GetPointIds().SetId(0, id0) line.GetPointIds().SetId(1, id1) connection_lines.InsertNextCell(line) connection_polydata.SetPoints(connection_points) connection_polydata.SetLines(connection_lines) connection_model = slicer.vtkMRMLModelNode() connection_model.SetScene(scene) connection_model.SetName("Connection to Fold Curve") connection_model.SetAndObservePolyData(connection_polydata) # model display node connection_model_display = slicer.vtkMRMLModelDisplayNode() connection_model_display.SetColor(0, 0, 0) connection_model_display.SetScene(scene) connection_model_display.SetLineWidth(3.0) connection_model_display.SetBackfaceCulling(0) scene.AddNode(connection_model_display) connection_model.SetAndObserveDisplayNodeID( connection_model_display.GetID()) scene.AddNode(connection_model)
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 run(self, enableScreenshots=0, screenshotScaleFactor=1): """ Run the actual algorithm """ self.delayDisplay( 'Running test of the Neurosurgical Planning tutorial') self.enableScreenshots = enableScreenshots self.screenshotScaleFactor = screenshotScaleFactor # conventional layout lm = slicer.app.layoutManager() lm.setLayout(2) moduleSelector = slicer.util.mainWindow().moduleSelector() # # first load the data # if self.enableScreenshots == 1: # for the tutorial, do it through the welcome module moduleSelector.selectModule('Welcome') self.delayDisplay("Screenshot") self.takeScreenshot('NeurosurgicalPlanning-Welcome', 'Welcome module', -1) else: # otherwise show the sample data module moduleSelector.selectModule('SampleData') # use the sample data module logic to load data for the self test import SampleData sampleDataLogic = SampleData.SampleDataLogic() self.delayDisplay("Getting Baseline volume") baselineVolume = sampleDataLogic.downloadWhiteMatterExplorationBaselineVolume( ) self.delayDisplay("Getting DTI volume") dtiVolume = sampleDataLogic.downloadWhiteMatterExplorationDTIVolume() self.takeScreenshot('NeurosurgicalPlanning-Loaded', 'Data loaded', -1) # # create a label map and set it for editing # volumesLogic = slicer.modules.volumes.logic() baselineVolumeLabel = volumesLogic.CreateAndAddLabelVolume( slicer.mrmlScene, baselineVolume, baselineVolume.GetName() + '-label') baselineDisplayNode = baselineVolumeLabel.GetDisplayNode() baselineDisplayNode.SetAndObserveColorNodeID( 'vtkMRMLColorTableNodeFileGenericAnatomyColors.txt') selectionNode = slicer.app.applicationLogic().GetSelectionNode() selectionNode.SetReferenceActiveVolumeID(baselineVolume.GetID()) selectionNode.SetReferenceActiveLabelVolumeID( baselineVolumeLabel.GetID()) slicer.app.applicationLogic().PropagateVolumeSelection(0) data = slicer.util.array(baselineVolume.GetName() + "-label") data[6:15, 110:140, 130:160] = 293 # # link the viewers # if self.enableScreenshots == 1: # for the tutorial, pop up the linking control sliceController = slicer.app.layoutManager().sliceWidget( "Red").sliceController() popupWidget = sliceController.findChild("ctkPopupWidget") if popupWidget is not None: popupWidget.pinPopup(1) self.takeScreenshot('NeurosurgicalPlanning-Link', 'Link slice viewers', -1) popupWidget.pinPopup(0) # # Tractography Label Map Seeding module # moduleSelector.selectModule('TractographyLabelMapSeeding') self.takeScreenshot('NeurosurgicalPlanning-LabelMapSeedingModule', 'Showing Tractography Label Seeding Module', -1) tractographyLabelSeeding = slicer.modules.tractographylabelmapseeding parameters = {} parameters['InputVolume'] = dtiVolume.GetID() baselinelabel293 = slicer.mrmlScene.GetFirstNodeByName( "BaselineVolume-label") # VTK6 TODO - set 'InputROIPipelineInfo' parameters['InputROI'] = baselinelabel293.GetID() fibers = slicer.vtkMRMLFiberBundleNode() slicer.mrmlScene.AddNode(fibers) parameters['OutputFibers'] = fibers.GetID() parameters['UseIndexSpace'] = 1 parameters['StoppingValue'] = 0.15 parameters['ROIlabel'] = 293 parameters['ThresholdMode'] = 'FractionalAnisotropy' # defaults # parameters['ClTh'] = 0.3 # parameters['MinimumLength'] = 20 # parameters['MaximumLength'] = 800 # parameters['StoppingCurvature'] = 0.7 # parameters['IntegrationStepLength'] = 0.5 # parameters['SeedSpacing'] = 2 # and run it slicer.cli.run(tractographyLabelSeeding, None, parameters) self.takeScreenshot('NeurosurgicalPlanning-LabelMapSeeding', 'Showing Tractography Label Seeding Results', -1) # # tractography fiducial seeding # moduleSelector.selectModule('TractographyInteractiveSeeding') self.takeScreenshot('NeurosurgicalPlanning-TIS', 'Showing Tractography Interactive Seeding Module', -1) # DTI in background sliceLogic = slicer.app.layoutManager().sliceWidget('Red').sliceLogic() sliceLogic.StartSliceCompositeNodeInteraction(1) compositeNode = sliceLogic.GetSliceCompositeNode() compositeNode.SetBackgroundVolumeID(dtiVolume.GetID()) sliceLogic.EndSliceCompositeNodeInteraction() # DTI visible in 3D sliceNode = sliceLogic.GetSliceNode() sliceLogic.StartSliceNodeInteraction(128) sliceNode.SetSliceVisible(1) sliceLogic.EndSliceNodeInteraction() self.takeScreenshot( 'NeurosurgicalPlanning-TIS-DTI', 'DTI volume with Tractography Interactive Seeding Module', -1) # place a fiducial displayNode = slicer.vtkMRMLMarkupsDisplayNode() slicer.mrmlScene.AddNode(displayNode) fidNode = slicer.vtkMRMLMarkupsFiducialNode() fidNode.SetName('F') slicer.mrmlScene.AddNode(fidNode) fidNode.SetAndObserveDisplayNodeID(displayNode.GetID()) r = 28.338526 a = 34.064367 sliceOffset = 58.7 s = sliceOffset fidNode.AddFiducial(r, a, s) # make it active selectionNode = slicer.mrmlScene.GetNodeByID( "vtkMRMLSelectionNodeSingleton") if (selectionNode is not None): selectionNode.SetReferenceActivePlaceNodeID(fidNode.GetID()) self.takeScreenshot( 'NeurosurgicalPlanning-TIS-Fid1', 'Fiducial in Tractography Interactive Seeding Module', -1) # set up the arguments wr = slicer.modules.tractographyinteractiveseeding.widgetRepresentation( ) wr.setDiffusionTensorVolumeNode(dtiVolume) # create a fiber bundle fiducialFibers = slicer.vtkMRMLFiberBundleNode() slicer.mrmlScene.AddNode(fiducialFibers) wr.setFiberBundleNode(fiducialFibers) wr.setSeedingNode(fidNode) wr.setMinimumPath(10) wr.setStoppingValue(0.15) self.takeScreenshot('NeurosurgicalPlanning-TIS-Args', 'Tractography Interactive Seeding arguments', -1) self.delayDisplay("Moving the fiducial") for y in range(-20, 100, 5): msg = "Moving the fiducial to y = " + str(y) self.delayDisplay(msg, 250) fidNode.SetNthFiducialPosition(0, r, y, s) self.takeScreenshot( 'NeurosurgicalPlanning-TIS-Moved', 'Moved fiducial and did Tractography Interactive Seeding', -1) return True
def run(self): """ Run the actual algorithm """ print('Running test of the markups in different views') # # first load the data # import SampleData sampleDataLogic = SampleData.SampleDataLogic() print("Getting MR Head Volume") mrHeadVolume = sampleDataLogic.downloadMRHead() # # link the viewers # sliceLogic = slicer.app.layoutManager().sliceWidget('Red').sliceLogic() compositeNode = sliceLogic.GetSliceCompositeNode() compositeNode.SetLinkedControl(1) # # MR Head in the background # sliceLogic.StartSliceCompositeNodeInteraction(1) compositeNode.SetBackgroundVolumeID(mrHeadVolume.GetID()) sliceLogic.EndSliceCompositeNodeInteraction() # # switch to conventional layout # lm = slicer.app.layoutManager() lm.setLayout(2) # create a fiducial list displayNode = slicer.vtkMRMLMarkupsDisplayNode() slicer.mrmlScene.AddNode(displayNode) fidNode = slicer.vtkMRMLMarkupsFiducialNode() slicer.mrmlScene.AddNode(fidNode) fidNode.SetAndObserveDisplayNodeID(displayNode.GetID()) # make it active selectionNode = slicer.mrmlScene.GetNodeByID("vtkMRMLSelectionNodeSingleton") if (selectionNode is not None): selectionNode.SetReferenceActivePlaceNodeID(fidNode.GetID()) # add some known points to it eye1 = [33.4975, 79.4042, -10.2143] eye2 = [-31.283, 80.9652, -16.2143] nose = [4.61944, 114.526, -33.2143] index = fidNode.AddFiducialFromArray(eye1) fidNode.SetNthFiducialLabel(index, "eye-1") index = fidNode.AddFiducialFromArray(eye2) fidNode.SetNthFiducialLabel(index, "eye-2") # hide the second eye as a test of visibility flags fidNode.SetNthFiducialVisibility(index, 0) index = fidNode.AddFiducialFromArray(nose) fidNode.SetNthFiducialLabel(index, "nose") self.logicDelayDisplay("Placed 3 fiducials") # self.printViewAndSliceNodes() if self.widgetVisible(fidNode, 'vtkMRMLViewNode1') == 0: self.logicDelayDisplay("Test failed: widget is not visible in view 1") # self.printViewNodeIDs(displayNode) return False # # switch to 2 3D views layout # lm.setLayout(15) self.logicDelayDisplay("Switched to 2 3D views") # self.printViewAndSliceNodes() if self.widgetVisible(fidNode, 'vtkMRMLViewNode1') == 0 or self.widgetVisible(fidNode, 'vtkMRMLViewNode2') == 0: self.logicDelayDisplay("Test failed: widget is not visible in view 1 and 2") # self.printViewNodeIDs(displayNode) return False # # show only in view 2 # displayNode.AddViewNodeID("vtkMRMLViewNode2") self.logicDelayDisplay("Showing only in view 2") if self.widgetVisible(fidNode, 'vtkMRMLViewNode1') == 1: self.logicDelayDisplay("Test failed: widget is not supposed to be visible in view 1") # self.printViewNodeIDs(displayNode) return False if self.widgetVisible(fidNode, 'vtkMRMLViewNode2') == 0: self.logicDelayDisplay("Test failed: widget is not visible in view 2") # self.printViewNodeIDs(displayNode) return False # # remove it so show in all # displayNode.RemoveAllViewNodeIDs() self.logicDelayDisplay("Showing in both views") if self.widgetVisible(fidNode, 'vtkMRMLViewNode1') == 0 or self.widgetVisible(fidNode, 'vtkMRMLViewNode2') == 0: self.logicDelayDisplay("Test failed: widget is not visible in view 1 and 2") self.printViewNodeIDs(displayNode) return False # # show only in view 1 # displayNode.AddViewNodeID("vtkMRMLViewNode1") self.logicDelayDisplay("Showing only in view 1") if self.widgetVisible(fidNode, 'vtkMRMLViewNode2') == 1: self.logicDelayDisplay("Test failed: widget is not supposed to be visible in view 2") # self.printViewNodeIDs(displayNode) return False if self.widgetVisible(fidNode, 'vtkMRMLViewNode1') == 0: self.logicDelayDisplay("Test failed: widget is not visible in view 1") # self.printViewNodeIDs(displayNode) return False # switch back to conventional lm.setLayout(2) self.logicDelayDisplay("Switched back to conventional layout") # self.printViewAndSliceNodes() # test of the visibility in slice views displayNode.RemoveAllViewNodeIDs() # jump to the last fiducial slicer.modules.markups.logic().JumpSlicesToNthPointInMarkup(fidNode.GetID(), index, 1) # refocus the 3D cameras as well slicer.modules.markups.logic().FocusCamerasOnNthPointInMarkup(fidNode.GetID(), index) # show only in red displayNode.AddViewNodeID('vtkMRMLSliceNodeRed') self.logicDelayDisplay("Show only in red slice") if self.widgetVisibleOnSlice(fidNode,'vtkMRMLSliceNodeRed') != 1: self.logicDelayDisplay("Test failed: widget not displayed on red slice") # self.printViewNodeIDs(displayNode) return False # remove all, add green # print 'before remove all, after added red' # self.printViewNodeIDs(displayNode) displayNode.RemoveAllViewNodeIDs() # print 'after removed all' # self.printViewNodeIDs(displayNode) displayNode.AddViewNodeID('vtkMRMLSliceNodeGreen') self.logicDelayDisplay('Show only in green slice') if self.widgetVisibleOnSlice(fidNode,'vtkMRMLSliceNodeRed') != 0 or self.widgetVisibleOnSlice(fidNode,'vtkMRMLSliceNodeGreen') != 1: self.logicDelayDisplay("Test failed: widget not displayed only on green slice") print '\tred = ',self.widgetVisibleOnSlice(fidNode,'vtkMRMLSliceNodeRed') print '\tgreen =',self.widgetVisibleOnSlice(fidNode,'vtkMRMLSliceNodeGreen') self.printViewNodeIDs(displayNode) return False return True