Skip to content

Commit

Permalink
ENH:: Crop Volumes generated from roi
Browse files Browse the repository at this point in the history
Also corrected signal and slot that link inputVolume ui to MRML scene.
  • Loading branch information
amymmorton committed Dec 13, 2024
1 parent fcdf1e0 commit ee6f64a
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,47 @@
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<item row="3" column="0" colspan="2">
<widget class="QPushButton" name="showBounds_pb">
<property name="text">
<string>Show Model Bounds</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="inputVol_label">
<property name="text">
<string>Input: Volume Node</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="qMRMLNodeComboBox" name="volumeSelector">
<property name="enabled">
<bool>true</bool>
</property>
<property name="nodeTypes">
<stringlist notr="true">
<string>vtkMRMLScalarVolumeNode</string>
</stringlist>
</property>
<property name="showChildNodeTypes">
<bool>true</bool>
</property>
<property name="hideChildNodeTypes">
<stringlist/>
</property>
<property name="noneEnabled">
<bool>true</bool>
</property>
<property name="interactionNodeSingletonTag">
<string>Singleton</string>
</property>
<property name="SlicerParamterName" stdset="0">
<string>inputVolume</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
Expand All @@ -50,14 +84,14 @@
<string>SubVol From ROI</string>
</property>
<layout class="QFormLayout" name="formLayout_4">
<item row="1" column="0">
<item row="0" column="0">
<widget class="QLabel" name="modelROI_label">
<property name="text">
<string>Model ROI</string>
</property>
</widget>
</item>
<item row="1" column="1">
<item row="0" column="1">
<widget class="qMRMLNodeComboBox" name="modelROISelector">
<property name="enabled">
<bool>false</bool>
Expand Down Expand Up @@ -87,14 +121,14 @@
</property>
</widget>
</item>
<item row="2" column="0">
<item row="1" column="0">
<widget class="QLabel" name="croppedVol_label">
<property name="text">
<string>Cropped volume:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<item row="1" column="1">
<widget class="qMRMLNodeComboBox" name="cropVolSelector">
<property name="enabled">
<bool>false</bool>
Expand Down Expand Up @@ -124,40 +158,6 @@
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="qMRMLNodeComboBox" name="volumeSelector">
<property name="enabled">
<bool>true</bool>
</property>
<property name="nodeTypes">
<stringlist notr="true">
<string>vtkMRMLScalarVolumeNode</string>
</stringlist>
</property>
<property name="showChildNodeTypes">
<bool>false</bool>
</property>
<property name="hideChildNodeTypes">
<stringlist/>
</property>
<property name="noneEnabled">
<bool>false</bool>
</property>
<property name="interactionNodeSingletonTag">
<string>Singleton</string>
</property>
<property name="SlicerParamterName" stdset="0">
<string>inputVolume</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="inputVol_label">
<property name="text">
<string>Input Volume</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
Expand Down Expand Up @@ -213,8 +213,8 @@
<y>135</y>
</hint>
<hint type="destinationlabel">
<x>220</x>
<y>161</y>
<x>326</x>
<y>237</y>
</hint>
</hints>
</connection>
Expand All @@ -229,8 +229,24 @@
<y>8</y>
</hint>
<hint type="destinationlabel">
<x>173</x>
<y>176</y>
<x>279</x>
<y>263</y>
</hint>
</hints>
</connection>
<connection>
<sender>roiFromModelBounds</sender>
<signal>mrmlSceneChanged(vtkMRMLScene*)</signal>
<receiver>volumeSelector</receiver>
<slot>setMRMLScene(vtkMRMLScene*)</slot>
<hints>
<hint type="sourcelabel">
<x>225</x>
<y>229</y>
</hint>
<hint type="destinationlabel">
<x>282</x>
<y>76</y>
</hint>
</hints>
</connection>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,10 @@ class roiFromModelBoundsParameterNode:

modelFile_path: pathlib.Path
inputVolume: vtkMRMLScalarVolumeNode
modelBounds: float
#modelBounds: float
modelROI: vtkMRMLMarkupsROINode
croppedVolume: vtkMRMLScalarVolumeNode
altVol: vtkMRMLScalarVolumeNode


#
Expand Down Expand Up @@ -289,6 +290,8 @@ def getParameterNode(self):

def loadModelsComputeBounds(self):
parameterNode = self.getParameterNode()
#TO DO error checking on model path and volume node

modelFileDir = parameterNode.modelFile_path

modelFiles = glob.glob(os.path.join(modelFileDir, "*.*"))
Expand All @@ -297,10 +300,13 @@ def loadModelsComputeBounds(self):
for _indx, file in enumerate(modelFiles):
modelNode = slicer.util.loadNodeFromFile(file)
modelNode.CreateDefaultDisplayNodes()
self.modelBounds(modelNode) #, volumeNode, self.ui.modelROISelector, self.ui.cropVolSelector)
roi_this = self.modelBounds(modelNode)
parameterNode.modelROI =roi_this
#parameterNode.croppedVolume = self.doCropVolume()
self.doCropVolume()


def modelBounds(self, inputModel) -> None:
def modelBounds(self, inputModel):

inputModel: vtkMRMLModelNode

Expand Down Expand Up @@ -333,6 +339,51 @@ def modelBounds(self, inputModel) -> None:
roi_name = mname + "_roi"
modelROI.SetName(roi_name)

return modelROI


def doCropVolume(self)->None:

parameterNode = self.getParameterNode()
#TO DO error checking on model path and volume node

inVolume = parameterNode.inputVolume
roi = parameterNode.modelROI

fillValue = 0.0
interpolate = False
spacingScalingConst = 1.0
isotropicResampling = False
interpolationMode = slicer.vtkMRMLCropVolumeParametersNode().InterpolationLinear
cropLogic = slicer.modules.cropvolume.logic()
cvpn = slicer.vtkMRMLCropVolumeParametersNode()

cvpn.SetROINodeID(roi.GetID())
cvpn.SetInputVolumeNodeID(inVolume.GetID())
cvpn.SetFillValue(fillValue)
cvpn.SetVoxelBased(not interpolate)
cvpn.SetSpacingScalingConst(spacingScalingConst)
cvpn.SetIsotropicResampling(isotropicResampling)
cvpn.SetInterpolationMode(interpolationMode)
cropLogic.Apply(cvpn)
roi.SetDisplayVisibility(False)

outputVolumeNodeID = cvpn.GetOutputVolumeNodeID()
#https://www.slicer.org/wiki/Documentation/4.3/Developers/Python_scripting
views = slicer.app.layoutManager().sliceViewNames()
for view in views:
view_logic = slicer.app.layoutManager().sliceWidget(view).sliceLogic()
view_cn = view_logic.GetSliceCompositeNode()
view_cn.SetBackgroundVolumeID(outputVolumeNodeID)
view_logic.FitSliceToAll()

#TO DO rename with model file name
outVolNode = cvpn.GetOutputVolumeNode
#TO DO wrong format- this is 'cropvole' needs to be 'scalarVolume'
#return outVolNode




#
# roiFromModelBoundsTest
Expand Down Expand Up @@ -367,37 +418,4 @@ def test_roiFromModelBounds1(self):
your test should break so they know that the feature is needed.
"""

self.delayDisplay("Starting the test")

# Get/create input data

import SampleData

registerSampleData()
inputModel = SampleData.downloadSample("roiFromModelBounds1")
self.delayDisplay("Loaded test data set")

inputScalarRange = inputModel.GetImageData().GetScalarRange()
self.assertEqual(inputScalarRange[0], 0)
self.assertEqual(inputScalarRange[1], 695)

outputVolume = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLScalarVolumeNode")
threshold = 100

# Test the module logic

logic = roiFromModelBoundsLogic()

# Test algorithm with non-inverted threshold
logic.process(inputModel, outputVolume, threshold, True)
outputScalarRange = outputVolume.GetImageData().GetScalarRange()
self.assertEqual(outputScalarRange[0], inputScalarRange[0])
self.assertEqual(outputScalarRange[1], threshold)

# Test algorithm with inverted threshold
logic.process(inputModel, outputVolume, threshold, False)
outputScalarRange = outputVolume.GetImageData().GetScalarRange()
self.assertEqual(outputScalarRange[0], inputScalarRange[0])
self.assertEqual(outputScalarRange[1], inputScalarRange[1])

self.delayDisplay("Test passed")
self.delayDisplay("TO DO configure test for this module ")

0 comments on commit ee6f64a

Please sign in to comment.