Skip to content

Commit

Permalink
ENH: renamed interface to ImageRegistrationTool (issue SlicerProstate…
Browse files Browse the repository at this point in the history
  • Loading branch information
che85 committed Jan 24, 2018
1 parent 0ba87b8 commit 768f6dd
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 46 deletions.
2 changes: 1 addition & 1 deletion SliceTracker/Resources/default.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
class: OpenSourceZFrameRegistration

[Prostate Registration]
Algorithm: BRAINSRegistration
Tool: BRAINSRegistration
Fallback: BRAINSRegistration

[Series Descriptions]
Expand Down
42 changes: 21 additions & 21 deletions SliceTracker/SliceTrackerRegistration.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class SliceTrackerRegistrationWidget(ScriptedLoadableModuleWidget, ModuleWidgetM

def __init__(self, parent=None):
ScriptedLoadableModuleWidget.__init__(self, parent)
self.registrationAlgorithm = None
self.imageRegistrationTool = None
self.counter = 1

def setup(self):
Expand All @@ -64,25 +64,25 @@ def setup(self):
showChildNodeTypes=False, selectNodeUponCreation=False,
toolTip="Select the Targets")

self.algorithmSelector = qt.QComboBox()
self.algorithmSelector.addItems(registration.__algorithms__.keys())
self.imageRegistrationToolSelector = qt.QComboBox()
self.imageRegistrationToolSelector.addItems(registration.__tools__.keys())

self.applyRegistrationButton = self.createButton("Run Registration")
self.registrationGroupBoxLayout.addRow("Moving Image Volume: ", self.movingVolumeSelector)
self.registrationGroupBoxLayout.addRow("Moving Label Volume: ", self.movingLabelSelector)
self.registrationGroupBoxLayout.addRow("Fixed Image Volume: ", self.fixedVolumeSelector)
self.registrationGroupBoxLayout.addRow("Fixed Label Volume: ", self.fixedLabelSelector)
self.registrationGroupBoxLayout.addRow("Targets: ", self.fiducialSelector)
self.registrationGroupBoxLayout.addRow("Algorithm:", self.algorithmSelector)
self.registrationGroupBoxLayout.addRow("Image Registration Tool:", self.imageRegistrationToolSelector)
self.registrationGroupBoxLayout.addRow(self.applyRegistrationButton)
self.layout.addWidget(self.registrationGroupBox)
self.layout.addStretch()
self.setupConnections()
self.onAlgorithmSelected(0)
self.onImageRegistrationToolSelected(0)

def setupConnections(self):
self.applyRegistrationButton.clicked.connect(self.runRegistration)
self.algorithmSelector.currentIndexChanged.connect(self.onAlgorithmSelected)
self.imageRegistrationToolSelector.currentIndexChanged.connect(self.onImageRegistrationToolSelected)
self.movingVolumeSelector.connect('currentNodeChanged(bool)', self.updateButton)
self.fixedVolumeSelector.connect('currentNodeChanged(bool)', self.updateButton)
self.fixedLabelSelector.connect('currentNodeChanged(bool)', self.updateButton)
Expand All @@ -102,16 +102,16 @@ def updateButton(self):
self.yellowCompositeNode.SetBackgroundVolumeID(self.fixedVolumeSelector.currentNode().GetID())
if self.fixedLabelSelector.currentNode():
self.yellowCompositeNode.SetLabelVolumeID(self.fixedLabelSelector.currentNode().GetID())
self.applyRegistrationButton.enabled = self.isRegistrationPossible() and self.registrationAlgorithm is not None
self.applyRegistrationButton.enabled = self.isRegistrationPossible() and self.imageRegistrationTool is not None

def onAlgorithmSelected(self, index):
text = self.algorithmSelector.itemText(index)
algorithm = registration.__algorithms__[text]
if algorithm.isAlgorithmAvailable():
self.registrationAlgorithm = algorithm
def onImageRegistrationToolSelected(self, index):
text = self.imageRegistrationToolSelector.itemText(index)
imageRegistrationTool = registration.__tools__[text]
if imageRegistrationTool.isToolAvailable():
self.imageRegistrationTool = imageRegistrationTool
else:
logging.info("Selected algorithm {} seems not to be available due to missing dependencies".format(text))
self.registrationAlgorithm = None
self.imageRegistrationTool = None
self.updateButton()

def isRegistrationPossible(self):
Expand All @@ -122,7 +122,7 @@ def runRegistration(self):
logging.debug("Starting Registration")
self.progress = self.createProgressDialog(value=1, maximum=4)

logic = SliceTrackerRegistrationLogic(self.registrationAlgorithm())
logic = SliceTrackerRegistrationLogic(self.imageRegistrationTool())

parameterNode = logic.initializeParameterNode(self.fixedVolumeSelector.currentNode(),
self.fixedLabelSelector.currentNode(),
Expand Down Expand Up @@ -158,13 +158,13 @@ def initializeParameterNode(fixedVolume, fixedLabel, movingVolume, movingLabel,

def __init__(self, algorithm):
ScriptedLoadableModuleLogic.__init__(self)
self.registrationAlgorithm = algorithm
self.imageRegistrationTool = algorithm

def run(self, parameterNode, result, progressCallback=None):
self.registrationAlgorithm.run(parameterNode, result, progressCallback)
self.imageRegistrationTool.run(parameterNode, result, progressCallback)

def getResult(self):
return self.registrationAlgorithm.registrationResult
return self.imageRegistrationTool.registrationResult


def main(argv):
Expand All @@ -183,7 +183,7 @@ def main(argv):
parser.add_argument("-o", "--output-directory", dest="output_directory", metavar="PATH", default="-",
required=False, help="Output directory for registration result")
parser.add_argument("-al", "--algorithm", dest="algorithm", metavar="PATH", default="BRAINS",
choices=registration.__algorithms__.keys(), required=False,
choices=registration.__tools__.keys(), required=False,
help="Algorithm to be used for registration (default: %(default)s)")

args = parser.parse_args(argv)
Expand All @@ -197,12 +197,12 @@ def main(argv):
success, fixedVolume = slicer.util.loadVolume(args.fixed_volume, returnNode=True)
success, movingVolume = slicer.util.loadVolume(args.moving_volume, returnNode=True)

algorithm = registration.__algorithms__[args.algorithm]
imageRegistrationTool = registration.__tools__[args.algorithm]

if not algorithm.isAlgorithmAvailable():
if not imageRegistrationTool.isToolAvailable():
raise RuntimeError("Registration algorithm {} cannot be executed due to missing dependencies.".format(args.algorithm))

logic = SliceTrackerRegistrationLogic(algorithm())
logic = SliceTrackerRegistrationLogic(imageRegistrationTool())
parameterNode = logic.initializeParameterNode(fixedVolume, fixedLabel, movingVolume, movingLabel)
logic.run(parameterNode, result=RegistrationResult("01: RegistrationResult"))

Expand Down
14 changes: 7 additions & 7 deletions SliceTracker/SliceTrackerUtils/algorithms/registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
from SlicerDevelopmentToolboxUtils.mixins import ModuleLogicMixin


class IRegistrationAlgorithm(ModuleLogicMixin):
class ImageRegistrationTool(ModuleLogicMixin):

__metaclass__ = ABCMeta

NAME = None

@staticmethod
def isAlgorithmAvailable():
def isToolAvailable():
raise NotImplementedError

def __init__(self):
Expand Down Expand Up @@ -72,12 +72,12 @@ def updateProgress(self, **kwargs):
self.progressCallback(**kwargs)


class BRAINSRegistration(IRegistrationAlgorithm):
class BRAINSRegistration(ImageRegistrationTool):

NAME = "BRAINSFit"

@staticmethod
def isAlgorithmAvailable():
def isToolAvailable():
return hasattr(slicer.modules, "brainsfit")

def __init__(self):
Expand Down Expand Up @@ -200,12 +200,12 @@ def run(self):
self.params = "BSpline Registration Parameters: %s" % str(params) + "\n\n"


class ElastixRegistration(IRegistrationAlgorithm):
class ElastixRegistration(ImageRegistrationTool):

NAME = "Elastix"

@staticmethod
def isAlgorithmAvailable():
def isToolAvailable():
try:
from Elastix import ElastixLogic
except ImportError:
Expand Down Expand Up @@ -273,5 +273,5 @@ def __runElastixRegistration(self):
self.updateProgress(labelText='\nCompleted registration', value=4)


__algorithms__ = {'BRAINS':BRAINSRegistration, 'Elastix':ElastixRegistration}
__tools__ = {'BRAINS':BRAINSRegistration, 'Elastix':ElastixRegistration}

4 changes: 2 additions & 2 deletions SliceTracker/SliceTrackerUtils/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ def loadConfiguration(self):
if not self.getSetting("ZFrame_Registration_Class_Name"):
self.setSetting("ZFrame_Registration_Class_Name", config.get('ZFrame Registration', 'class'))

if not self.getSetting("Prostate_Registration_Algorithm"):
self.setSetting("Prostate_Registration_Algorithm", config.get('Prostate Registration', 'Algorithm'))
if not self.getSetting("Prostate_Registration_Tool"):
self.setSetting("Prostate_Registration_Tool", config.get('Prostate Registration', 'Tool'))

if not self.getSetting("Prostate_Registration_Fallback"):
self.setSetting("Prostate_Registration_Fallback", config.get('Prostate Registration', 'Fallback'))
Expand Down
13 changes: 7 additions & 6 deletions SliceTracker/SliceTrackerUtils/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -724,15 +724,16 @@ def _runRegistration(self, parameterNode, segmentationData, progressCallback):
self.invokeEvent(self.InitiateEvaluationEvent)

def getRegistrationLogic(self):
preferred = self.getSetting("Prostate_Registration_Algorithm")
preferred = self.getSetting("Prostate_Registration_Tool")
fallback = self.getSetting("Prostate_Registration_Fallback")
registrationClass = getattr(sys.modules[__name__], preferred)
if not registrationClass.isAlgorithmAvailable():
registrationClass = getattr(sys.modules[__name__], fallback)
if not registrationClass.isAlgorithmAvailable():
registrationToolClass = getattr(sys.modules[__name__], preferred)
if not registrationToolClass.isToolAvailable():
registrationToolClass = getattr(sys.modules[__name__], fallback)
if not registrationToolClass.isToolAvailable():
raise RuntimeError("Neither preferred registration algorithm: {}, nor fallback registration algorithm {}"
"are available. Make sure to install required dependencies".format(preferred, fallback))
return SliceTrackerRegistrationLogic(registrationClass())
logging.info("Preferred registration algorithm: {} not available. Falling back to {}. ".format(preferred, fallback))
return SliceTrackerRegistrationLogic(registrationToolClass())

def addTargetsToMRMLScene(self, result):
targetNodes = result.targets.asDict()
Expand Down
23 changes: 14 additions & 9 deletions puml/SliceTrackerRegistration.puml
Original file line number Diff line number Diff line change
@@ -1,29 +1,34 @@
@startuml

!include RegistrationResults.puml

class SliceTrackerRegistrationLogic {
+ IRegistrationAlgorithm algorithm;
+ ImageRegistrationTool imageRegistrationTool;
--
+ run()
}

IRegistrationAlgorithm <-- SliceTrackerRegistrationLogic::algorithm: has_a

ImageRegistrationTool <.. SliceTrackerRegistrationLogic::imageRegistrationTool: has_a

SliceTrackerRegistrationLogic <-- SliceTrackerRegistrationWidget: uses
SliceTrackerRegistrationLogic <-- CLI: uses


interface IRegistrationAlgorithm {
interface ImageRegistrationTool {
+ NAME: None
+ {static} isAlgorithmAvailable()
+ registrationResult: RegistrationResult
+ {static} isToolAvailable()
+ {abstract} run(parameterNode, registrationResult, progressCallback=None)
# _processParameterNode(parameterNode)
+ updateProgress(**kwargs)
}

RegistrationResult <.. ImageRegistrationTool::registrationResult: has_a


class BRAINRegistration {
+ NAME="BRAINSFit"
+ isAlgorithmAvailable()
+ isToolAvailable()
+ run(self, parameterNode, result, progressCallback=None)
- __runRigidRegistration()
- __runAffineRegistration()
Expand All @@ -32,7 +37,7 @@ class BRAINRegistration {

class ElastixRegistration {
+ NAME="Elastix"
+ isAlgorithmAvailable()
+ isToolAvailable()
+ run(self, parameterNode, result, progressCallback=None)
- __runRigidBRAINSRegistration()
- __runElastixRegistration()
Expand All @@ -44,8 +49,8 @@ BRAINSRigidRegistration <-- BRAINRegistration::__runRigidRegistration: uses
BRAINSAffineRegistration <-- BRAINRegistration::__runAffineRegistration: uses
BRAINSBSplineRegistration <-- BRAINRegistration::__runBSplineRegistration: uses

IRegistrationAlgorithm <|-- BRAINRegistration: is_a
IRegistrationAlgorithm <|-- ElastixRegistration: is_a
ImageRegistrationTool <|-- BRAINRegistration: is_a
ImageRegistrationTool <|-- ElastixRegistration: is_a

interface IBRAINSRegistrationType{
+ fixedVolume
Expand Down

0 comments on commit 768f6dd

Please sign in to comment.