Skip to content

Commit

Permalink
ENH: add capability to init from existing segmentations
Browse files Browse the repository at this point in the history
Added an attribute on the finding node to pass along the id of a
prior segemented label map volume to use when adding a finding.
The module workflow is split up across multiple small functions
so the passing of the prior volume information isn't as clean
as it could be with a redesign.

Issue QIICR#1
  • Loading branch information
Nicole Aucoin committed Jun 19, 2015
1 parent c709109 commit 0294511
Show file tree
Hide file tree
Showing 5 changed files with 246 additions and 20 deletions.
64 changes: 63 additions & 1 deletion Py/qSlicerLongitudinalPETCTModuleWidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from SlicerLongitudinalPETCTModuleSegmentationHelper import SlicerLongitudinalPETCTModuleSegmentationHelper as SegmentationHelper

from Editor import EditorWidget
from LabelStatistics import LabelStatisticsLogic

import sys as SYS

Expand Down Expand Up @@ -919,11 +920,26 @@ def onFindingNodeAdded(self, finding):

name = dialog.property("findingName")
colorid = dialog.property("findingColorID")
priorLabelMapID = dialog.property("findingPriorSegmentationID")

if (len(name) > 0) & (colorid != -1):
finding.SetName(name)
finding.SetColorID(colorid)

if (len(priorLabelMapID) > 0):
print 'Initializing segmentation from prior'
study = self.getActiveStudy()
segmentationNode = finding.GetSegmentationMappedByStudyNodeID(study.GetID())
# Can init from a prior label map if no segmentation node has been
# defined yet, or it has but it doesn't already point to the prior
# label map
if (segmentationNode == None or
segmentationNode.GetLabelVolumeID() == None or
(segmentationNode.GetLabelVolumeID() != None and segmentationNode.GetLabelVolumeID() != priorLabelMapID)):
finding.SetAttribute("AssociatedNodeID", priorLabelMapID)
else:
print 'Unable to initialize from prior label map with id',priorLabelMapID,', segmentationNode = ',segmentationNode

self.activeReportNode.AddFindingNodeID(finding.GetID())
self.reportOverviewWidget.selectFindingRow(self.activeReportNode.GetIndexOfFindingNodeID(finding.GetID()))

Expand Down Expand Up @@ -1321,7 +1337,47 @@ def __prepareVolumesForSegmentation(self,caller,event):
if self.__tempLabelVol == None:
self.__createTempLabelVolume()

if finding.GetAttribute("AssociatedNodeID"):
# init from the prior segmentation, then unset
priorSegmentationID = finding.GetAttribute("AssociatedNodeID")
print 'prepareVolumesForSegmentation: Finding has an associated prior: ',priorSegmentationID
priorSegmentationNode = slicer.mrmlScene.GetNodeByID(priorSegmentationID)
if priorSegmentationNode:
# threshold the prior to the finding value
findingColor = finding.GetColorID()
print 'Threshold the prior to the finding color',findingColor
threshold = vtk.vtkImageThreshold()
threshold.SetInputData(priorSegmentationNode.GetImageData())
threshold.SetReplaceOut(0)
threshold.SetReplaceIn(1)
threshold.SetInValue(findingColor)
# set all non zero values to the finding color
scalarRange = [0,0]
priorSegmentationNode.GetImageData().GetScalarRange(scalarRange)
print '\tprior scalarRange = ',scalarRange
threshold.ThresholdBetween(1, scalarRange[1])
threshold.Update()
threshold.ReleaseDataFlagOn()
priorSegmentationNode.SetAndObserveImageData(threshold.GetOutputDataObject(0))
# put the prior into the PET label volume so that it will be in
# the pipeine for segmentation
if (study.GetPETLabelVolumeNode().GetImageData() != None):
# check that the geometry matches
volumesLogic = slicer.modules.volumes.logic()
geometryCheckString = volumesLogic.CheckForLabelVolumeValidity(study.GetPETLabelVolumeNode(), priorSegmentationNode)
if geometryCheckString != "":
print 'Resampling prior due to geometry mismatch:\n',geometryCheckString
resampledSegmentationNode = volumesLogic.ResampleVolumeToReferenceVolume(priorSegmentationNode, study.GetPETLabelVolumeNode())
study.GetPETLabelVolumeNode().Copy(resampledSegmentationNode)
else:
# geometry matches
study.GetPETLabelVolumeNode().Copy(priorSegmentationNode)
else:
# just copy to init it
study.GetPETLabelVolumeNode().Copy(priorSegmentationNode)

self.__tempLabelVol.Copy(study.GetPETLabelVolumeNode())

self.__tempLabelVol.SetName("LongitudinalPETCT_CroppedLabelVolume")
self.__tempLabelVol.SetSaveWithScene(False)

Expand Down Expand Up @@ -1386,6 +1442,12 @@ def onAddSegmentationToFinding(self):
SegmentationHelper.removeSegmentationFromVolume(seg.GetLabelVolumeNode(), finding.GetColorID())

pasted = SegmentationHelper.pasteFromCroppedToMainLabelVolume(self.__tempLabelVol, seg.GetLabelVolumeNode(), finding.GetColorID())

# if there was a prior, unset it now (if done before this, it can get
# over written or cropped out)
if finding.GetAttribute("AssociatedNodeID"):
finding.RemoveAttribute("AssociatedNodeID")

#set coordinates and extent of roi used for segmentation
c = [0.,0.,0.]
r = [0.,0.,0.]
Expand Down Expand Up @@ -1445,7 +1507,7 @@ def calculateSUVsAndStatistics(self, study, finding):
if (study == None) | (finding == None):
return

stats = LabelStatisticsLogic(study.GetPETVolumeNode(), study.GetPETLabelVolumeNode())
stats = LabelStatistics.LabelStatisticsLogic(study.GetPETVolumeNode(), study.GetPETLabelVolumeNode())

if finding.GetColorID() in stats.labelStats["Labels"]:
idx = stats.labelStats["Labels"].index(finding.GetColorID())
Expand Down
71 changes: 69 additions & 2 deletions Resources/UI/qMRMLLongitudinalPETCTFindingSettingsDialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>374</width>
<height>209</height>
<height>317</height>
</rect>
</property>
<property name="sizePolicy">
Expand Down Expand Up @@ -294,6 +294,56 @@ Node</string>
</property>
</widget>
</item>
<item>
<widget class="ctkCollapsibleButton" name="InitializeFromPriorSegmentationCollapsibleButton">
<property name="toolTip">
<string>Select a segmented volume from the scene, resample and threshold</string>
</property>
<property name="text">
<string>Initialize from Prior Segmentation</string>
</property>
<property name="collapsed">
<bool>true</bool>
</property>
<property name="contentsFrameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<layout class="QFormLayout" name="formLayout_3">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::FieldsStayAtSizeHint</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="PriorSegmentationLabel">
<property name="text">
<string>Segmentations:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="qMRMLNodeComboBox" name="PriorSegmentationMRMLNodeComboBox">
<property name="toolTip">
<string>Select a label map volume from the scene. It will be resampled and thresholded if necessary to match the current image geometry. If there are multiple values present, they will be thresholded to the selected finding color.</string>
</property>
<property name="nodeTypes">
<stringlist>
<string>vtkMRMLLabelMapVolumeNode</string>
</stringlist>
</property>
<property name="noneEnabled">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="Line" name="line_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="ButtonBox">
<property name="standardButtons">
Expand All @@ -306,10 +356,27 @@ Node</string>
<customwidgets>
<customwidget>
<class>qMRMLLabelComboBox</class>
<extends>QWidget</extends>
<extends>qMRMLWidget</extends>
<header>qMRMLLabelComboBox.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>qMRMLNodeComboBox</class>
<extends>QWidget</extends>
<header>qMRMLNodeComboBox.h</header>
</customwidget>
<customwidget>
<class>qMRMLWidget</class>
<extends>QWidget</extends>
<header>qMRMLWidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>ctkCollapsibleButton</class>
<extends>QWidget</extends>
<header>ctkCollapsibleButton.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../qSlicerLongitudinalPETCTModule.qrc"/>
Expand Down
Loading

0 comments on commit 0294511

Please sign in to comment.