Ejemplo n.º 1
0
    def __init__(self, MODULE, title="Xnat Download", memDisplay="MB"):
        """ Init funnction.
        """
        super(XnatDownloadPopup, self).__init__(MODULE=MODULE, title=title)

        #-------------------
        # Params
        #-------------------
        self.memDisplay = memDisplay
        self.downloadFileSize = None

        #-------------------
        # Window size
        #-------------------
        self.window.setFixedWidth(500)

        #-------------------
        # Line text
        #-------------------
        self.textDisp = [
            '', '[Unknown amount] ' + self.memDisplay +
            ' out of [Unknown total] ' + self.memDisplay
        ]
        self.lines = [qt.QLabel('') for x in range(0, 2)]

        #-------------------
        # Prog bar
        #-------------------
        self.progBar = qt.QProgressBar(self.window)
        self.progBar.setFixedHeight(17)

        #-------------------
        # Cancel button
        #-------------------
        self.cancelButton = qt.QPushButton()
        self.cancelButton.setText("Cancel")
        self.cancelButton.connect('pressed()',
                                  self.MODULE.XnatIo.cancelDownload)
        self.cancelButton.setFixedWidth(60)

        #-------------------
        # Add widgets to layout
        #-------------------
        for l in self.lines:
            self.layout.addRow(l)
        self.layout.addRow(self.progBar)

        #-------------------
        # Cancel row
        #-------------------
        cancelRow = qt.QHBoxLayout()
        cancelRow.addStretch()
        cancelRow.addWidget(self.cancelButton)
        cancelRow.addSpacing(37)
        self.layout.addRow(cancelRow)

        #-------------------
        # Clear all
        #-------------------
        self.reset()
Ejemplo n.º 2
0
    def createUserInterface(self):
        self.__layout = self.__parent.createUserInterface()

        self.__spacerLabel = qt.QLabel(" ")
        self.__layout.addRow(self.__spacerLabel)

        self.__spacerLabel = qt.QLabel("The results look good!")
        self.__layout.addRow(self.__spacerLabel)

        self.__spacerLabel = qt.QLabel("Degree of affectation by stenosis:")
        self.__layout.addRow(self.__spacerLabel)

        self.__affectationGrad = qt.QProgressBar()
        self.__affectationGrad.value = 35
        self.__layout.addRow(self.__affectationGrad)
 def createBusyProgressBarDialog(text):
   
   dialog = qt.QDialog()
   dialog.setModal(True)
   
   vbl = qt.QVBoxLayout(dialog)
   
   lbl = qt.QLabel(text, dialog)
   lbl.setAlignment(qt.Qt.AlignCenter)
     
   pb = qt.QProgressBar(dialog)
   pb.setMinimum(0)
   pb.setMaximum(0)
   pb.setTextVisible(False)
   pb.setMinimumWidth(lbl.sizeHint.width())
      
   vbl.addWidget(lbl)
   vbl.addWidget(pb)
     
   return dialog
Ejemplo n.º 4
0
    def __init__(self, parent=None):
        super(AddProgresWin, self).__init__(parent)

        #self.thread = SleepProgress()

        self.nameLabel = qt.QLabel("0.0%")
        self.nameLine = qt.QLineEdit()

        self.taskLabel = qt.QLabel(
            "The volume is being processed. Please wait...")

        self.progressbar = qt.QProgressBar()
        self.progressbar.setMinimum(0)
        self.progressbar.setMaximum(0)

        mainLayout = qt.QVBoxLayout()
        mainLayout.addWidget(self.taskLabel)
        mainLayout.addWidget(self.progressbar)
        #mainLayout.addWidget(self.nameLabel, 0, 1)

        self.setLayout(mainLayout)
        self.setWindowTitle("Work in progress")
        self.setWindowModality(True)
Ejemplo n.º 5
0
    def addDownloadRow(self, uri, size=-1):
        """ Constructs a download row object based
            on the URI
        """

        #-------------------
        # Cancel button row
        #-------------------
        rowWidget = qt.QWidget()
        rowWidget.setObjectName('downloadRowWidget')
        rowWidget.setStyleSheet(
            '#downloadRowWidget {border: 1px ' +
            ' solid rgb(160,160,160); border-radius: 2px; width: 100%;}')
        #rowWidget.setFixedHeight(self.rowWidgetHeight)
        #rowWidget.setSizePolicy(qt.QSizePolicy.MinimumExpanding,
        #                        qt.QSizePolicy.MinimumExpanding)
        layout = qt.QVBoxLayout()
        rowWidget.setLayout(layout)

        #-------------------
        # Text Edit
        #-------------------
        textEdit = qt.QTextEdit()
        textEdit.setStyleSheet("border: none")
        textEdit.setFixedHeight(55)
        textEdit.verticalScrollBar().hide()
        textEdit.setFont(
            qt.QFont(XnatDownloadPopup.FONT_NAME, XnatDownloadPopup.FONT_SIZE,
                     10, False))
        layout.addWidget(textEdit)

        #-------------------
        # Progress Bar
        #-------------------
        progressBar = qt.QProgressBar(rowWidget)
        progressBar.setFixedHeight(17)
        progressBar.setFixedWidth(600)
        progressBar.setMinimum(0)
        progressBar.setMaximum(100)
        progressBar.setAlignment(0x0084)

        #-------------------
        # Cancel button row
        #-------------------
        cancelButton = qt.QPushButton()
        cancelButton.setText("Cancel")
        cancelButton.setFont(XnatDownloadPopup.LABEL_FONT)
        cancelButton.setFixedWidth(60)
        cancelButton.setFixedHeight(19)

        #-------------------
        # Progress bar row
        #-------------------
        progressRow = qt.QHBoxLayout()
        progressRow.addWidget(progressBar)
        progressRow.addStretch()
        progressRow.addWidget(cancelButton)
        layout.addLayout(progressRow)

        #-------------------
        # Row dict
        #-------------------
        downloadRow = {
            'queuePosition': len(self.downloadRows),
            'size': 0,
            'downloaded': 0,
            'textEdit': textEdit,
            'pathDict': XnatSlicerUtils.getXnatPathDict(uri),
            'progressBar': progressBar,
            'widget': rowWidget,
            'cancelButton': cancelButton
        }

        #-------------------
        # default text
        #-------------------
        dlStr = self.makeDownloadPath(downloadRow['pathDict'])
        textEdit.setText("QUEUED<br>%s<br>Please wait...<br>" % (dlStr))

        #-------------------
        # Cancel callback
        #-------------------
        def cancelClick():
            rowWidget.setEnabled(False)
            #print "Cancelling download '%s'"%(dlStr)
            textEdit.setText(textEdit.toHtml().replace('DOWNLOADING',
                                                       'CANCELLED'))
            for key, item in self.downloadRows.iteritems():
                if item['progressBar'] == progressBar:
                    item['progressBar'].setEnabled(False)
                    item['progressBar'].setMaximum(100)
                    self.cancelCallback(key)

        cancelButton.connect('pressed()', cancelClick)

        self.downloadRows[uri] = downloadRow
        self.remakeWidget()
Ejemplo n.º 6
0
    def setup(self):
        # Instantiate and connect widgets ...

        #
        # Filters Area
        #
        filtersCollapsibleButton = ctk.ctkCollapsibleButton()
        filtersCollapsibleButton.text = "Filters"
        self.layout.addWidget(filtersCollapsibleButton)
        # Layout within the dummy collapsible button
        filtersFormLayout = qt.QFormLayout(filtersCollapsibleButton)

        # filter search
        self.searchBox = ctk.ctkSearchBox()
        filtersFormLayout.addRow("Search:", self.searchBox)
        self.searchBox.connect("textChanged(QString)", self.onSearch)

        # filter selector
        self.filterSelector = qt.QComboBox()
        filtersFormLayout.addRow("Filter:", self.filterSelector)

        # add all the filters listed in the json files
        for idx, j in enumerate(self.jsonFilters):
            name = j["name"]
            self.filterSelector.addItem(name, idx)

        # connections
        self.filterSelector.connect('currentIndexChanged(int)',
                                    self.onFilterSelect)

        #
        # Parameters Area
        #
        parametersCollapsibleButton = ctk.ctkCollapsibleButton()
        parametersCollapsibleButton.text = "Parameters"
        self.layout.addWidget(parametersCollapsibleButton)

        # Layout within the dummy collapsible button
        parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton)

        self.filterParameters = FilterParameters(parametersCollapsibleButton)

        # Add vertical spacer
        self.layout.addStretch(1)

        #
        # Status and Progress
        #
        statusLabel = qt.QLabel("Status: ")
        self.currentStatusLabel = qt.QLabel("Idle")
        hlayout = qt.QHBoxLayout()
        hlayout.addStretch(1)
        hlayout.addWidget(statusLabel)
        hlayout.addWidget(self.currentStatusLabel)
        self.layout.addLayout(hlayout)

        self.progress = qt.QProgressBar()
        self.progress.setRange(0, 1000)
        self.progress.setValue(0)
        self.layout.addWidget(self.progress)
        self.progress.hide()

        #
        # Cancel/Apply Row
        #
        self.restoreDefaultsButton = qt.QPushButton("Restore Defaults")
        self.restoreDefaultsButton.toolTip = "Restore the default parameters."
        self.restoreDefaultsButton.enabled = True

        self.cancelButton = qt.QPushButton("Cancel")
        self.cancelButton.toolTip = "Abort the algorithm."
        self.cancelButton.enabled = False

        self.applyButton = qt.QPushButton("Apply")
        self.applyButton.toolTip = "Run the algorithm."
        self.applyButton.enabled = True

        hlayout = qt.QHBoxLayout()

        hlayout.addWidget(self.restoreDefaultsButton)
        hlayout.addStretch(1)
        hlayout.addWidget(self.cancelButton)
        hlayout.addWidget(self.applyButton)
        self.layout.addLayout(hlayout)

        # connections
        self.restoreDefaultsButton.connect('clicked(bool)',
                                           self.onRestoreDefaultsButton)
        self.applyButton.connect('clicked(bool)', self.onApplyButton)
        self.cancelButton.connect('clicked(bool)', self.onCancelButton)

        # Initlial Selection
        self.filterSelector.currentIndexChanged(
            self.filterSelector.currentIndex)
Ejemplo n.º 7
0
 def __init__(self):
     self.pb = qt.QProgressBar()
 def __init__(self):
     # Create a Progress Bar
     self.pb = qt.QProgressBar()
Ejemplo n.º 9
0
    def setup(self):
        frame = qt.QFrame()
        frameLayout = qt.QFormLayout()
        frame.setLayout(frameLayout)
        self.parent.layout().addWidget(frame)

        # Choose directory button to choose the folder for saving the registered image
        self.directoryButton = qt.QPushButton(
            "Choose folder with the segmented images")
        self.directoryButton.setFont(qt.QFont(self.font_type, self.font_size))
        self.directoryButton.toolTip = "Choose a folder of .nii or .img/.hdr images of the segmented bones."
        frameLayout.addWidget(self.directoryButton)
        self.directoryButton.connect('clicked()', self.onDirectoryButtonClick)
        frameLayout.addRow(self.directoryButton)

        # Choose the Output folder button to choose the folder for saving the registered image
        self.outputDirectoryButton = qt.QPushButton(
            "Choose folder to save the output training data to")
        self.outputDirectoryButton.setFont(
            qt.QFont(self.font_type, self.font_size))
        self.outputDirectoryButton.toolTip = "Choose a folder to save the output"
        frameLayout.addWidget(self.outputDirectoryButton)
        self.outputDirectoryButton.connect('clicked()',
                                           self.onOutputDirectoryButtonClick)
        frameLayout.addRow(self.outputDirectoryButton)

        # ICP Registration Collapse button
        self.ICPCollapsibleButton = ctk.ctkCollapsibleButton()
        self.ICPCollapsibleButton.setFont(
            qt.QFont(self.font_type, self.font_size))
        self.ICPCollapsibleButton.text = "Iterative Closest Point Registration"
        self.ICPCollapsibleButton.collapsed = True  # Default is to not show
        frameLayout.addWidget(self.ICPCollapsibleButton)

        # Layout within the ICP collapsible button
        self.ICPFormLayout = qt.QFormLayout(self.ICPCollapsibleButton)

        # Slider for Maximum Iteration Number for ICP registration
        self.label = qt.QLabel()
        self.label.setFont(qt.QFont(self.font_type, self.font_size))
        self.label.setText("Maximum Iteration Number: ")
        self.label.setToolTip(
            "Select the maximum iteration number for the ICP registration.")
        self.IterationSlider = ctk.ctkSliderWidget()
        self.IterationSlider.setToolTip(
            "Select the maximum iteration number for the ICP registration.")
        self.IterationSlider.minimum = 1
        self.IterationSlider.maximum = 200
        self.IterationSlider.value = 100
        self.IterationSlider.singleStep = 5
        self.IterationSlider.tickInterval = 1
        self.IterationSlider.decimals = 0
        self.IterationSlider.connect('valueChanged(double)',
                                     self.onIterationSliderChange)
        self.ICPFormLayout.addRow(self.label, self.IterationSlider)
        self.IterationNumber = self.IterationSlider.value  # Set default value

        # Slider for Number of Landmarks for ICP
        self.label = qt.QLabel()
        self.label.setFont(qt.QFont(self.font_type, self.font_size))
        self.label.setText("ICP Landmark Number: ")
        self.label.setToolTip(
            "Select the number of landmarks per surface for the ICP registration."
        )
        self.LandmarkSlider = ctk.ctkSliderWidget()
        self.LandmarkSlider.setToolTip(
            "Select the number of landmarks per surface for the ICP registration."
        )
        self.LandmarkSlider.minimum = 50
        self.LandmarkSlider.maximum = 1000
        self.LandmarkSlider.value = 500
        self.LandmarkSlider.singleStep = 10
        self.LandmarkSlider.tickInterval = 1
        self.LandmarkSlider.decimals = 0
        self.LandmarkSlider.connect('valueChanged(double)',
                                    self.onLandmarkSliderChange)
        self.ICPFormLayout.addRow(self.label, self.LandmarkSlider)
        self.LandmarkNumber = self.LandmarkSlider.value  # Set default value

        # Slider for Maximum RMS Error for ICP
        self.label = qt.QLabel()
        self.label.setFont(qt.QFont(self.font_type, self.font_size))
        self.label.setText("ICP Maximum RMS Error: ")
        self.label.setToolTip(
            "Select the maximum root mean square (RMS) error for determining the ICP registration convergence."
        )
        self.RMS_Slider = ctk.ctkSliderWidget()
        self.RMS_Slider.setToolTip(
            "Select the maximum root mean square (RMS) error for determining the ICP registration convergence."
        )
        self.RMS_Slider.minimum = 0.0001
        self.RMS_Slider.maximum = 0.05
        self.RMS_Slider.value = 0.01
        self.RMS_Slider.singleStep = 0.01
        self.RMS_Slider.tickInterval = 0.001
        self.RMS_Slider.decimals = 3
        self.RMS_Slider.connect('valueChanged(double)',
                                self.onRMS_SliderChange)
        self.ICPFormLayout.addRow(self.label, self.RMS_Slider)
        self.RMS_Number = self.RMS_Slider.value  # Set default value

        # Slider for choosing the reference bone
        self.label = qt.QLabel()
        self.label.setFont(qt.QFont(self.font_type, self.font_size))
        self.label.setText("Reference Bone Label: ")
        self.label.setToolTip(
            "Select the label of the bone to keep static. This bone will be registered among all the volunteers. Note: Please choose the folder with the segmented images first."
        )
        self.Ref_Bone_Slider = ctk.ctkSliderWidget()
        self.Ref_Bone_Slider.setToolTip(
            "Select the label of the bone to keep static. This bone will be registered among all the volunteers. Note: Please choose the folder with the segmented images first."
        )
        self.Ref_Bone_Slider.minimum = 0
        self.Ref_Bone_Slider.maximum = 0
        self.Ref_Bone_Slider.value = 0
        self.Ref_Bone_Slider.singleStep = 1
        self.Ref_Bone_Slider.tickInterval = 1
        self.Ref_Bone_Slider.decimals = 0
        self.Ref_Bone_Slider.connect('valueChanged(double)',
                                     self.onRef_Bone_SliderChange)
        self.ICPFormLayout.addRow(self.label, self.Ref_Bone_Slider)
        self.ref_label = int(self.Ref_Bone_Slider.value)  # Set default value

        # Radial buttons for the ICP parameters
        self.radial_button_1 = qt.QRadioButton("Similarity")
        self.radial_button_1.setFont(qt.QFont(self.font_type, self.font_size))
        self.radial_button_1.toggled.connect(self.onICPModeSelect_1)
        self.ICPFormLayout.addWidget(self.radial_button_1)

        self.radial_button_2 = qt.QRadioButton("Rigid")
        self.radial_button_2.setFont(qt.QFont(self.font_type, self.font_size))
        self.radial_button_2.setChecked(True)
        self.radial_button_2.toggled.connect(self.onICPModeSelect_2)
        self.ICPFormLayout.addWidget(self.radial_button_2)

        self.radial_button_3 = qt.QRadioButton("Affine")
        self.radial_button_3.toggled.connect(self.onICPModeSelect_3)
        self.ICPFormLayout.addWidget(self.radial_button_3)

        # Text input for choosing which image labels to use
        self.label = qt.QLabel()
        self.label.setFont(qt.QFont(self.font_type, self.font_size))
        self.label.setText("Image Labels: ")
        self.label.setToolTip(
            "Choose several labels to use for creating the training data. Value of -1 uses the default 1 through 9. Otherwise, input should be similar to '1,2,3' to use labels one, two, and three. "
        )
        self.lineedit = qt.QLineEdit()
        self.lineedit.setFont(qt.QFont(self.font_type, self.font_size))
        self.lineedit.setToolTip(
            "Choose several labels to use for creating the training data. Value of -1 uses the default 1 through 9. Otherwise, input should be similar to '1,2,3' to use labels one, two, and three. "
        )
        self.ICPFormLayout.addRow(self.label, self.lineedit)
        self.lineedit.setText("-1")

        # Bone Smoothing Parameters Collapse Button
        self.SmoothCollapsibleButton = ctk.ctkCollapsibleButton()
        self.SmoothCollapsibleButton.setFont(
            qt.QFont(self.font_type, self.font_size))
        self.SmoothCollapsibleButton.text = "Smoothing Options"
        self.SmoothCollapsibleButton.collapsed = True  # Default is to not show
        frameLayout.addWidget(self.SmoothCollapsibleButton)

        # Layout within the smoothing options collapsible button
        self.SmoothFormLayout = qt.QFormLayout(self.SmoothCollapsibleButton)

        # Slider for choosing the number of iterations for bone smoothing
        self.label = qt.QLabel()
        self.label.setFont(qt.QFont(self.font_type, self.font_size))
        self.label.setText("Smoothing Iterations: ")
        self.label.setToolTip(
            "Select the number of iterations for smoothing the bone surface. Higher iterations will smooth more. Lower iterations will have less smoothing."
        )
        self.Bone_Smoothing_Its_Slider = ctk.ctkSliderWidget()
        self.Bone_Smoothing_Its_Slider.setToolTip(
            "Select the number of iterations for smoothing the bone surface. Higher iterations will smooth more. Lower iterations will have less smoothing."
        )
        self.Bone_Smoothing_Its_Slider.minimum = 0
        self.Bone_Smoothing_Its_Slider.maximum = 30
        self.Bone_Smoothing_Its_Slider.value = 10
        self.Bone_Smoothing_Its_Slider.singleStep = 1
        self.Bone_Smoothing_Its_Slider.tickInterval = 1
        self.Bone_Smoothing_Its_Slider.decimals = 0
        self.Bone_Smoothing_Its_Slider.connect(
            'valueChanged(double)', self.onBone_Smoothing_Its_SliderChange)
        self.SmoothFormLayout.addRow(self.label,
                                     self.Bone_Smoothing_Its_Slider)
        self.smoothing_iterations = self.Bone_Smoothing_Its_Slider.value  # Set default value

        # Slider for choosing the smoothing relaxation factor
        self.label = qt.QLabel()
        self.label.setFont(qt.QFont(self.font_type, self.font_size))
        self.label.setText("Relaxation Factor: ")
        self.label.setToolTip(
            "Select the relaxation factor for smoothing the bone surfaces. Higher relaxation will smooth the surface more while a lower factor will have less smoothing."
        )
        self.Bone_Smoothing_Relaxation_Slider = ctk.ctkSliderWidget()
        self.Bone_Smoothing_Relaxation_Slider.setToolTip(
            "Select the relaxation factor for smoothing the bone surfaces. Higher relaxation will smooth the surface more while a lower factor will have less smoothing."
        )
        self.Bone_Smoothing_Relaxation_Slider.minimum = 0
        self.Bone_Smoothing_Relaxation_Slider.maximum = 1
        self.Bone_Smoothing_Relaxation_Slider.value = 0.4
        self.Bone_Smoothing_Relaxation_Slider.singleStep = 0.1
        self.Bone_Smoothing_Relaxation_Slider.tickInterval = 0.1
        self.Bone_Smoothing_Relaxation_Slider.decimals = 2
        self.Bone_Smoothing_Relaxation_Slider.connect(
            'valueChanged(double)',
            self.onBone_Smoothing_Relaxation_SliderChange)
        self.SmoothFormLayout.addRow(self.label,
                                     self.Bone_Smoothing_Relaxation_Slider)
        self.relaxation_factor = self.Bone_Smoothing_Relaxation_Slider.value  # Set default value

        # Slider for choosing the percentage of bone surface decimation
        self.label = qt.QLabel()
        self.label.setFont(qt.QFont(self.font_type, self.font_size))
        self.label.setText("Surface Decimation: ")
        self.label.setToolTip(
            "Select the ratio of verticies to remove from the bone surface. This results in a smoother surface and less points for faster computation. Too much could cause surface artifacts. For example, 0.1 removes 10 percent while 0.9 removes 90 percent of points."
        )
        self.Bone_Decimate_Slider = ctk.ctkSliderWidget()
        self.Bone_Decimate_Slider.setToolTip(
            "Select the ratio of verticies to remove from the bone surface. This results in a smoother surface and less points for faster computation. Too much could cause surface artifacts. For example, 0.1 removes 10 percent while 0.9 removes 90 percent of points."
        )
        self.Bone_Decimate_Slider.minimum = 0
        self.Bone_Decimate_Slider.maximum = 0.9
        self.Bone_Decimate_Slider.value = 0
        self.Bone_Decimate_Slider.singleStep = 0.05
        self.Bone_Decimate_Slider.tickInterval = 0.05
        self.Bone_Decimate_Slider.decimals = 2
        self.Bone_Decimate_Slider.connect('valueChanged(double)',
                                          self.onBone_Decimate_SliderChange)
        self.SmoothFormLayout.addRow(self.label, self.Bone_Decimate_Slider)
        self.decimate_surface = self.Bone_Decimate_Slider.value  # Set default value

        # Debugging Collapse button
        self.RenderingCollapsibleButton = ctk.ctkCollapsibleButton()
        self.RenderingCollapsibleButton.setFont(
            qt.QFont(self.font_type, self.font_size))
        self.RenderingCollapsibleButton.text = "Visualization"
        self.RenderingCollapsibleButton.collapsed = True  # Default is to not show
        frameLayout.addWidget(self.RenderingCollapsibleButton)

        # Layout within the debug collapsible button
        self.CollapseFormLayout = qt.QFormLayout(
            self.RenderingCollapsibleButton)

        # Show the registered shapes toggle button
        self.show_registered_shapes = qt.QCheckBox("Show Registered Shapes")
        self.show_registered_shapes.setFont(
            qt.QFont(self.font_type, self.font_size))
        self.show_registered_shapes.toolTip = "When checked, show each registered bone. Useful for debugging any ICP registration based errors."
        self.show_registered_shapes.checked = False
        self.CollapseFormLayout.addWidget(self.show_registered_shapes)

        # Show the registered shapes toggle button
        self.show_extracted_shapes = qt.QCheckBox("Show Extracted Shapes")
        self.show_extracted_shapes.setFont(
            qt.QFont(self.font_type, self.font_size))
        self.show_extracted_shapes.toolTip = "When checked, show the initial surfaces from the images. Useful for debugging errors based on deriving surfaces from the MR images."
        self.show_extracted_shapes.checked = False
        self.CollapseFormLayout.addWidget(self.show_extracted_shapes)

        # Show the loaded images toggle button
        self.debug_show_images = qt.QCheckBox("Show Loaded Images")
        self.debug_show_images.setFont(qt.QFont(self.font_type,
                                                self.font_size))
        self.debug_show_images.toolTip = "When checked, show the loaded images. Useful for debugging if the images are flipped or loading incorrectly."
        self.debug_show_images.checked = False
        self.CollapseFormLayout.addWidget(self.debug_show_images)

        # Debugging Collapse button
        self.DebugCollapsibleButton = ctk.ctkCollapsibleButton()
        self.DebugCollapsibleButton.setFont(
            qt.QFont(self.font_type, self.font_size))
        self.DebugCollapsibleButton.text = "Debugging"
        self.DebugCollapsibleButton.collapsed = True  # Default is to not show
        frameLayout.addWidget(self.DebugCollapsibleButton)

        # Layout within the debug collapsible button
        self.CollapseFormLayout = qt.QFormLayout(self.DebugCollapsibleButton)

        # Show the flip image vertically toggle button
        self.flip_image_vertically = qt.QCheckBox("Flip Vertically")
        self.flip_image_vertically.setFont(
            qt.QFont(self.font_type, self.font_size))
        self.flip_image_vertically.toolTip = "When checked, flip the images vertically after loading them."
        self.flip_image_vertically.checked = False
        self.CollapseFormLayout.addWidget(self.flip_image_vertically)

        # Show the flip image horizontally toggle button
        self.flip_image_horizontally = qt.QCheckBox("Flip Horizontally")
        self.flip_image_horizontally.setFont(
            qt.QFont(self.font_type, self.font_size))
        self.flip_image_horizontally.toolTip = "When checked, flip the images horizontally after loading them."
        self.flip_image_horizontally.checked = False
        self.CollapseFormLayout.addWidget(self.flip_image_horizontally)

        # Show the save bones separately toggle button
        self.Save_Extracted_Bones_Separately = qt.QCheckBox(
            "Save Extracted Bones Separately")
        self.Save_Extracted_Bones_Separately.setFont(
            qt.QFont(self.font_type, self.font_size))
        self.Save_Extracted_Bones_Separately.toolTip = "When checked, save each bone surface separately after smoothing and before any registration."
        self.Save_Extracted_Bones_Separately.checked = False
        self.CollapseFormLayout.addWidget(self.Save_Extracted_Bones_Separately)

        # Show the save bones separately toggle button
        self.Save_Registered_Bones_Separately = qt.QCheckBox(
            "Save Registered Bones Separately")
        self.Save_Registered_Bones_Separately.setFont(
            qt.QFont(self.font_type, self.font_size))
        self.Save_Registered_Bones_Separately.toolTip = "When checked, save each bone surface separately after smoothing and registration (instead of combining all the bones for each volunteer/position together)."
        self.Save_Registered_Bones_Separately.checked = False
        self.CollapseFormLayout.addWidget(
            self.Save_Registered_Bones_Separately)

        # Skip the registration
        self.Skip_Registration = qt.QCheckBox("Skip Registration Steps")
        self.Skip_Registration.setFont(qt.QFont(self.font_type,
                                                self.font_size))
        self.Skip_Registration.toolTip = "When checked, extract each bone surface from the image and smooth the surface (this is useful if the user only wishes to extract the bones from the images and smooth them.) Consider using along with the save extracted bones setting."
        self.Skip_Registration.checked = False
        self.CollapseFormLayout.addWidget(self.Skip_Registration)

        # Don't save the reference bone toggle button
        self.Remove_Ref_Bone = qt.QCheckBox("Remove the reference bone")
        self.Remove_Ref_Bone.setFont(qt.QFont(self.font_type, self.font_size))
        self.Remove_Ref_Bone.toolTip = "When checked, don't save the refernce bone when saving the PLY file. For example, this is useful if using the radius as a reference bone, but if you don't want it to appear in the final model."
        self.Remove_Ref_Bone.checked = False
        self.CollapseFormLayout.addWidget(self.Remove_Ref_Bone)

        # Choose the number of files to load from the given folder
        self.label = qt.QLabel()
        self.label.setFont(qt.QFont(self.font_type, self.font_size))
        self.label.setText("Number of images: ")
        self.label.setToolTip(
            "Select how many images to use from the given folder. (Select the folder first). This is useful if want want to use just the first few images to make sure everything runs correctly."
        )
        self.NumFileSlider = ctk.ctkSliderWidget()
        self.NumFileSlider.setToolTip(
            "Select how many images to use from the given folder. (Select the folder first). This is useful if want want to use just the first few images to make sure everything runs correctly."
        )
        self.NumFileSlider.minimum = -1
        self.NumFileSlider.maximum = 1
        self.NumFileSlider.value = -1
        self.NumFileSlider.singleStep = 1
        self.NumFileSlider.tickInterval = 1
        self.NumFileSlider.decimals = 0
        self.NumFileSlider.connect('valueChanged(double)',
                                   self.onNumSliderChange)
        self.CollapseFormLayout.addRow(self.label, self.NumFileSlider)
        self.num_files = self.NumFileSlider.value  # Set default value

        # Compute button
        self.computeButton = qt.QPushButton("Create The Training Data")
        self.computeButton.setFont(qt.QFont(self.font_type, self.font_size))
        self.computeButton.toolTip = "Run the module and create the training data for the PCA bone displacement model."
        frameLayout.addWidget(self.computeButton)
        self.computeButton.connect('clicked()', self.onCompute)
        self.computeButton.enabled = False

        # Progress Bar (so the user knows how much longer it will take)
        self.progressBar = qt.QProgressBar()
        self.progressBar.setFont(qt.QFont(self.font_type, self.font_size))
        self.progressBar.setValue(0)
        frameLayout.addWidget(self.progressBar)
        self.progressBar.hide()
Ejemplo n.º 10
0
    def setup(self):
        #
        # Input
        #
        self.inputCollapsibleButton = ctk.ctkCollapsibleButton()
        self.inputCollapsibleButton.text = "Input"
        self.layout.addWidget(self.inputCollapsibleButton)

        # Layout within the input collapsible button
        self.inputFormLayout = qt.QFormLayout(self.inputCollapsibleButton)

        import platform
        self.inputJsonFn = ctk.ctkPathLineEdit()
        self.inputFormLayout.addRow("Input Json:", self.inputJsonFn)
        #self.inputJsonFn.setCurrentPath('input.json')
        if platform.system() == 'Linux':
            self.inputJsonFn.setCurrentPath(
                '/home/mrusu/Projects/RadPathFusion/prostate/4_histology/')
        if platform.system() == 'Windows':
            self.inputJsonFn.setCurrentPath(
                'C:/Projects/rad-path-fusion/prostate_RP/3_histology/')
        #self.inputJsonFn.setMaximumWidth(425)
        self.inputJsonFn.addCurrentPathToHistory()

        #
        # input fixed volume selector
        #
        self.inputVolumeSelector = slicer.qMRMLNodeComboBox()
        self.inputVolumeSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"]
        self.inputVolumeSelector.selectNodeUponCreation = True
        self.inputVolumeSelector.addEnabled = False
        self.inputVolumeSelector.renameEnabled = True
        self.inputVolumeSelector.removeEnabled = True
        self.inputVolumeSelector.noneEnabled = True
        self.inputVolumeSelector.showHidden = False
        self.inputVolumeSelector.showChildNodeTypes = False
        self.inputVolumeSelector.setMRMLScene(slicer.mrmlScene)
        self.inputFormLayout.addRow("Fixed Volume: ", self.inputVolumeSelector)

        #
        # input fixed volume selector
        #
        self.inputMaskSelector = slicer.qMRMLNodeComboBox()
        self.inputMaskSelector.nodeTypes = ["vtkMRMLLabelMapVolumeNode"]
        self.inputMaskSelector.selectNodeUponCreation = True
        self.inputMaskSelector.addEnabled = False
        self.inputMaskSelector.renameEnabled = True
        self.inputMaskSelector.removeEnabled = True
        self.inputMaskSelector.noneEnabled = True
        self.inputMaskSelector.showHidden = False
        self.inputMaskSelector.showChildNodeTypes = False
        self.inputMaskSelector.setMRMLScene(slicer.mrmlScene)
        self.inputFormLayout.addRow("Fixed Mask: ", self.inputMaskSelector)

        #
        #Output
        #
        self.outputCollapsibleButton = ctk.ctkCollapsibleButton()
        self.outputCollapsibleButton.text = "Output"
        self.layout.addWidget(self.outputCollapsibleButton)

        # Layout within the output collapsible button
        self.outputFormLayout = qt.QFormLayout(self.outputCollapsibleButton)
        """
        self.outputJsonFn = ctk.ctkPathLineEdit()
        self.outputFormLayout.addRow("Output Json:", self.outputJsonFn)
        if platform.system() == 'Linux':
            self.outputJsonFn.setCurrentPath('/home/mrusu/Projects/RadPathFusion/prostate/4_histology/')
        if platform.system() == 'Windows':
            self.outputJsonFn.setCurrentPath( 'C:/Projects/rad-path-fusion/prostate_RP/3_histology/')
            
        #self.outputJsonFn.setMaximumWidth(400)
        """

        #
        # output volume selector
        #
        self.outputVolumeSelector = slicer.qMRMLNodeComboBox()
        self.outputVolumeSelector.nodeTypes = ["vtkMRMLVectorVolumeNode"]
        self.outputVolumeSelector.selectNodeUponCreation = True
        self.outputVolumeSelector.addEnabled = True
        self.outputVolumeSelector.renameEnabled = True
        self.outputVolumeSelector.removeEnabled = True
        self.outputVolumeSelector.noneEnabled = True
        self.outputVolumeSelector.showHidden = False
        self.outputVolumeSelector.showChildNodeTypes = False
        self.outputVolumeSelector.setMRMLScene(slicer.mrmlScene)
        self.outputFormLayout.addRow("Output Volume: ",
                                     self.outputVolumeSelector)
        #self.outputVolumeSelector.setMaximumWidth(400)

        #
        # output mask volume selector
        #
        self.outputMaskVolumeSelector = slicer.qMRMLNodeComboBox()
        self.outputMaskVolumeSelector.nodeTypes = ["vtkMRMLLabelMapVolumeNode"]
        self.outputMaskVolumeSelector.selectNodeUponCreation = True
        self.outputMaskVolumeSelector.addEnabled = True
        self.outputMaskVolumeSelector.renameEnabled = True
        self.outputMaskVolumeSelector.removeEnabled = True
        self.outputMaskVolumeSelector.noneEnabled = True
        self.outputMaskVolumeSelector.showHidden = False
        self.outputMaskVolumeSelector.showChildNodeTypes = False
        self.outputMaskVolumeSelector.setMRMLScene(slicer.mrmlScene)
        # maskIDselector
        self.maskIdSelector = qt.QComboBox()
        self.populateMaskId()

        self.outputFormLayout.addRow("Output Mask: ",
                                     self.outputMaskVolumeSelector)
        self.outputFormLayout.addRow("Mask ID", self.maskIdSelector)
        #self.outputMaskVolumeSelector.setMaximumWidth(400)

        #
        # Status and Progress
        #
        statusLabel = qt.QLabel("Status: ")
        self.currentStatusLabel = qt.QLabel("Idle")
        hlayout = qt.QHBoxLayout()
        hlayout.addStretch(1)
        hlayout.addWidget(statusLabel)
        hlayout.addWidget(self.currentStatusLabel)
        self.layout.addLayout(hlayout)

        self.progress = qt.QProgressBar()
        self.progress.setRange(0, 0)
        #self.progress.setValue(0)
        self.layout.addWidget(self.progress)
        self.progress.hide()

        #Load Input
        self.loadJsonButton = qt.QPushButton("Load Json")
        self.loadJsonButton.toolTip = "Load the json file."
        self.loadJsonButton.enabled = True

        # Save Output Json
        self.saveJsonButton = qt.QPushButton("Save Json")
        self.saveJsonButton.toolTip = "Save the json file."
        self.saveJsonButton.enabled = False

        # ReconstructVolume
        self.refineVolumeButton = qt.QPushButton("Refine Volume")
        self.refineVolumeButton.toolTip = "Refine."
        self.refineVolumeButton.enabled = True

        # RegisterVolume
        self.registerVolumeButton = qt.QPushButton("Register")
        self.registerVolumeButton.toolTip = "Register"
        self.registerVolumeButton.enabled = True

        # LoadVolume
        self.loadVolumeButton = qt.QPushButton("Load Volume")
        self.loadVolumeButton.toolTip = "Load Volume."
        self.loadVolumeButton.enabled = True

        # LoadMask
        self.loadMaskVolumeButton = qt.QPushButton("Load Mask")
        self.loadMaskVolumeButton.toolTip = "Load a Mask"
        self.loadMaskVolumeButton.enabled = True

        # Clear
        self.clearAllVolumeButton = qt.QPushButton("Clear ALL")
        self.clearAllVolumeButton.toolTip = "Clear"
        self.clearAllVolumeButton.enabled = False

        hlayout = qt.QHBoxLayout()

        hlayout.addWidget(self.loadJsonButton)
        hlayout.addWidget(self.refineVolumeButton)
        hlayout.addWidget(self.registerVolumeButton)
        hlayout.addWidget(self.loadVolumeButton)
        hlayout.addWidget(self.loadMaskVolumeButton)
        hlayout.addWidget(self.clearAllVolumeButton)
        hlayout.addStretch(1)
        hlayout.addWidget(self.saveJsonButton)
        self.layout.addLayout(hlayout)

        self.loadJsonButton.connect('clicked(bool)', self.onLoadJson)
        self.saveJsonButton.connect('clicked(bool)', self.onSaveJson)
        self.refineVolumeButton.connect('clicked(bool)', self.onRefineVolume)
        self.registerVolumeButton.connect('clicked(bool)',
                                          self.onRegisterVolume)
        self.loadVolumeButton.connect('clicked(bool)', self.onLoadVolume)
        self.loadMaskVolumeButton.connect('clicked(bool)',
                                          self.onLoadMaskVolume)
        self.clearAllVolumeButton.connect('clicked(bool)', self.onClearAll)

        self.maskIdSelector.connect('currentIndexChanged(int)',
                                    self.onMaskIDSelect)

        #
        # advanced
        #
        self.advancedCollapsibleButton = ctk.ctkCollapsibleButton()
        self.advancedCollapsibleButton.text = "Advanced"
        self.layout.addWidget(self.advancedCollapsibleButton)
        self.advancedCollapsibleButton.enabled = False

        self.advancedFormLayout = qt.QFormLayout(
            self.advancedCollapsibleButton)

        # Add vertical spacer
        self.layout.addStretch(1)
    def setup(self):
        #
        # Configuration
        #
        self.configCollapsibleButton = ctk.ctkCollapsibleButton()
        self.configCollapsibleButton.text = "Configuration"
        self.layout.addWidget(self.configCollapsibleButton)

        # Layout within the configuration collapsible button
        self.configFormLayout = qt.QFormLayout(self.configCollapsibleButton)

        import platform
        self.elastixPath = ctk.ctkPathLineEdit()
        self.elastixPath.filters = ctk.ctkPathLineEdit.Dirs
        self.configFormLayout.addRow("Elastix Executable Path:",
                                     self.elastixPath)

        if platform.system() == 'Linux':
            self.elastixPath.setCurrentPath(
                '/home/mrusu/Programs/elastix-4.9.0-linux/bin/')
        if platform.system() == 'Windows':
            self.elastixPath.setCurrentPath("C:/Programs/elastix-4.9.0-win64/")

        self.slicerElastixPath = ctk.ctkPathLineEdit()
        self.slicerElastixPath.filters = ctk.ctkPathLineEdit.Dirs
        self.configFormLayout.addRow("Slicer Elastix Path:",
                                     self.slicerElastixPath)

        if platform.system() == 'Linux':
            self.slicerElastixPath.setCurrentPath(
                '/home/mrusu/Programs/SlicerElastix/Elastix')
        if platform.system() == 'Windows':
            self.slicerElastixPath.setCurrentPath(
                "C:/Programs/SlicerElastix/Elastix/")

        #
        # Input
        #
        self.inputCollapsibleButton = ctk.ctkCollapsibleButton()
        self.inputCollapsibleButton.text = "Input"
        self.layout.addWidget(self.inputCollapsibleButton)

        # Layout within the input collapsible button
        self.inputFormLayout = qt.QFormLayout(self.inputCollapsibleButton)

        #
        # rgb volume selector
        #
        self.inputVolumeSelector = slicer.qMRMLNodeComboBox()
        self.inputVolumeSelector.nodeTypes = ["vtkMRMLVectorVolumeNode"]
        self.inputVolumeSelector.selectNodeUponCreation = True
        self.inputVolumeSelector.addEnabled = False
        self.inputVolumeSelector.removeEnabled = False
        self.inputVolumeSelector.noneEnabled = False
        self.inputVolumeSelector.showHidden = False
        self.inputVolumeSelector.showChildNodeTypes = False
        self.inputVolumeSelector.setMRMLScene(slicer.mrmlScene)
        self.inputFormLayout.addRow("Fixed volume: ", self.inputVolumeSelector)

        ###
        """
        self.fixedVolumeMaskSelector = slicer.qMRMLNodeComboBox()
        self.fixedVolumeMaskSelector.nodeTypes = ["vtkMRMLLabelMapVolumeNode"]
        self.fixedVolumeMaskSelector.addEnabled = False
        self.fixedVolumeMaskSelector.removeEnabled = False
        self.fixedVolumeMaskSelector.noneEnabled = True
        self.fixedVolumeMaskSelector.showHidden = False
        self.fixedVolumeMaskSelector.showChildNodeTypes = False
        self.fixedVolumeMaskSelector.setMRMLScene( slicer.mrmlScene )
        self.inputFormLayout.addRow("Fixed volume mask: ", self.fixedVolumeMaskSelector)
        
        self.movingVolumeSelector = slicer.qMRMLNodeComboBox()
        self.movingVolumeSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"]
        self.movingVolumeSelector.selectNodeUponCreation = True
        self.movingVolumeSelector.addEnabled = False
        self.movingVolumeSelector.removeEnabled = False
        self.movingVolumeSelector.noneEnabled = False
        self.movingVolumeSelector.showHidden = False
        self.movingVolumeSelector.showChildNodeTypes = False
        self.movingVolumeSelector.setMRMLScene( slicer.mrmlScene )
        self.inputFormLayout.addRow("Moving volume: ", self.movingVolumeSelector)


        #
        # moving volume mask selector
        #
        self.movingVolumeMaskSelector = slicer.qMRMLNodeComboBox()
        self.movingVolumeMaskSelector.nodeTypes = ["vtkMRMLLabelMapVolumeNode"]
        self.movingVolumeMaskSelector.selectNodeUponCreation = True
        self.movingVolumeMaskSelector.addEnabled = False
        self.movingVolumeMaskSelector.removeEnabled = False
        self.movingVolumeMaskSelector.noneEnabled = True
        self.movingVolumeMaskSelector.showHidden = False
        self.movingVolumeMaskSelector.showChildNodeTypes = False
        self.movingVolumeMaskSelector.setMRMLScene( slicer.mrmlScene )
        self.movingVolumeMaskSelector.setToolTip("Moving volume mask")
        self.inputFormLayout.addRow("Moving volume mask: ", self.movingVolumeMaskSelector)
        """

        #
        #Output
        #
        self.outputCollapsibleButton = ctk.ctkCollapsibleButton()
        self.outputCollapsibleButton.text = "Output"
        self.layout.addWidget(self.outputCollapsibleButton)

        # Layout within the output collapsible button
        self.outputFormLayout = qt.QFormLayout(self.outputCollapsibleButton)

        #
        # output volume selector
        #
        self.outputVolumeSelector = slicer.qMRMLNodeComboBox()
        self.outputVolumeSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"]
        self.outputVolumeSelector.selectNodeUponCreation = True
        self.outputVolumeSelector.addEnabled = True
        self.outputVolumeSelector.renameEnabled = True
        self.outputVolumeSelector.removeEnabled = True
        self.outputVolumeSelector.noneEnabled = True
        self.outputVolumeSelector.showHidden = False
        self.outputVolumeSelector.showChildNodeTypes = False
        self.outputVolumeSelector.setMRMLScene(slicer.mrmlScene)
        self.outputFormLayout.addRow("Output volume: ",
                                     self.outputVolumeSelector)
        """
        #
        # output transform selector
        #
        self.outputTransformSelector = slicer.qMRMLNodeComboBox()
        self.outputTransformSelector.nodeTypes = ["vtkMRMLTransformNode"]
        self.outputTransformSelector.selectNodeUponCreation = True
        self.outputTransformSelector.addEnabled = True
        self.outputTransformSelector.renameEnabled = True
        self.outputTransformSelector.removeEnabled = True
        self.outputTransformSelector.noneEnabled = True
        self.outputTransformSelector.showHidden = False
        self.outputTransformSelector.showChildNodeTypes = False
        self.outputTransformSelector.setMRMLScene( slicer.mrmlScene )
        self.outputFormLayout.addRow("Output transform: ", self.outputTransformSelector)

        """
        # Add vertical spacer
        self.layout.addStretch(1)

        #
        # Status and Progress
        #
        statusLabel = qt.QLabel("Status: ")
        self.currentStatusLabel = qt.QLabel("Idle")
        hlayout = qt.QHBoxLayout()
        hlayout.addStretch(1)
        hlayout.addWidget(statusLabel)
        hlayout.addWidget(self.currentStatusLabel)
        self.layout.addLayout(hlayout)

        self.progress = qt.QProgressBar()
        self.progress.setRange(0, 1000)
        self.progress.setValue(0)
        self.layout.addWidget(self.progress)
        self.progress.hide()

        #Cancel
        self.cancelButton = qt.QPushButton("Cancel")
        self.cancelButton.toolTip = "Abort the algorithm."
        self.cancelButton.enabled = False

        # Apply button
        self.applyButton = qt.QPushButton("Apply")
        self.applyButton.toolTip = "Run the Radiology-Pathology Fusion."
        self.applyButton.enabled = True

        # Test button
        self.testButton = qt.QPushButton("Test")
        self.testButton.toolTip = "Text elastix."
        self.testButton.enabled = True

        hlayout = qt.QHBoxLayout()

        hlayout.addWidget(self.testButton)
        hlayout.addStretch(1)
        hlayout.addWidget(self.cancelButton)
        hlayout.addWidget(self.applyButton)
        self.layout.addLayout(hlayout)

        self.cancelButton.connect('clicked(bool)', self.onCancel)
        self.applyButton.connect('clicked(bool)', self.onApply)
        self.testButton.connect('clicked(bool)', self.onTest)
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)
        self.logic = DualModalityCalibrationLogic()

        # Instantiate and connect widgets

        #
        # Calibration Parameters Area
        #
        parametersCollapsibleButton = ctk.ctkCollapsibleButton()
        parametersCollapsibleButton.text = "Calibration input and output transforms"
        self.layout.addWidget(parametersCollapsibleButton)

        # Layout within the dummy collapsible button
        parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton)

        #
        # Optical tracking system transform selector
        #
        self.opticalPointerSelectorLabel = qt.QLabel()
        self.opticalPointerSelectorLabel.setText(
            "OpPointerToOpRef Transform: ")
        self.opticalPointerSelector = slicer.qMRMLNodeComboBox()
        self.opticalPointerSelector.nodeTypes = ([
            "vtkMRMLLinearTransformNode"
        ])
        self.opticalPointerSelector.noneEnabled = False
        self.opticalPointerSelector.addEnabled = False
        self.opticalPointerSelector.removeEnabled = True
        self.opticalPointerSelector.setMRMLScene(slicer.mrmlScene)
        self.opticalPointerSelector.setToolTip(
            "Pick a known transform corresponding to the optical pointer's coordinate frame"
        )
        parametersFormLayout.addRow(self.opticalPointerSelectorLabel,
                                    self.opticalPointerSelector)

        #
        # Em tracking system transform selector
        #
        self.EmPointerSelectorLabel = qt.QLabel()
        self.EmPointerSelectorLabel.setText("EmPointerToEmTracker Transform: ")
        self.emPointerSelector = slicer.qMRMLNodeComboBox()
        self.emPointerSelector.nodeTypes = (["vtkMRMLTransformNode"])
        self.emPointerSelector.noneEnabled = False
        self.emPointerSelector.addEnabled = False
        self.emPointerSelector.removeEnabled = True
        self.emPointerSelector.setMRMLScene(slicer.mrmlScene)
        self.emPointerSelector.setToolTip(
            "Pick a known transform corresponding to the Em pointer's coordinate frame"
        )
        parametersFormLayout.addRow(self.EmPointerSelectorLabel,
                                    self.emPointerSelector)

        #
        # Initial landmark registration result transform selector
        #
        self.initialEmTrackerToOpRefSelectorLabel = qt.QLabel()
        self.initialEmTrackerToOpRefSelectorLabel.setText(
            "Initial EmTrackerToOpRef Transform: ")
        self.initialEmTrackerToOpRefSelector = slicer.qMRMLNodeComboBox()
        self.initialEmTrackerToOpRefSelector.nodeTypes = ([
            "vtkMRMLTransformNode"
        ])
        self.initialEmTrackerToOpRefSelector.noneEnabled = False
        self.initialEmTrackerToOpRefSelector.addEnabled = True
        self.initialEmTrackerToOpRefSelector.removeEnabled = True
        self.initialEmTrackerToOpRefSelector.baseName = "EmTrackerToOpRefInitial"
        self.initialEmTrackerToOpRefSelector.setMRMLScene(slicer.mrmlScene)
        self.initialEmTrackerToOpRefSelector.setToolTip(
            "Pick a known transform corresponding to the Em pointer's coordinate frame"
        )
        parametersFormLayout.addRow(self.initialEmTrackerToOpRefSelectorLabel,
                                    self.initialEmTrackerToOpRefSelector)

        self.outputEmTrackerToOpRefTransformSelectorLabel = qt.QLabel(
            "Output EmTrackerToOpRef transform: ")
        self.outputEmTrackerToOpRefTransformSelector = slicer.qMRMLNodeComboBox(
        )
        self.outputEmTrackerToOpRefTransformSelector.nodeTypes = ([
            "vtkMRMLTransformNode"
        ])
        self.outputEmTrackerToOpRefTransformSelector.noneEnabled = True
        self.outputEmTrackerToOpRefTransformSelector.addEnabled = True
        self.outputEmTrackerToOpRefTransformSelector.removeEnabled = True
        self.outputEmTrackerToOpRefTransformSelector.baseName = "EmTrackerToOpRef"
        self.outputEmTrackerToOpRefTransformSelector.setMRMLScene(
            slicer.mrmlScene)
        self.outputEmTrackerToOpRefTransformSelector.setToolTip(
            "Select the transform to output the EmTrackerToOpRef calibration result to"
        )
        parametersFormLayout.addRow(
            self.outputEmTrackerToOpRefTransformSelectorLabel,
            self.outputEmTrackerToOpRefTransformSelector)

        self.outputEmPointerGtruthToOpPointerTransformSelectorLabel = qt.QLabel(
            "Output EmPointerGtruthToOpPointer transform: ")
        self.outputEmPointerGtruthToOpPointerTransformSelector = slicer.qMRMLNodeComboBox(
        )
        self.outputEmPointerGtruthToOpPointerTransformSelector.nodeTypes = ([
            "vtkMRMLTransformNode"
        ])
        self.outputEmPointerGtruthToOpPointerTransformSelector.noneEnabled = True
        self.outputEmPointerGtruthToOpPointerTransformSelector.addEnabled = True
        self.outputEmPointerGtruthToOpPointerTransformSelector.removeEnabled = True
        self.outputEmPointerGtruthToOpPointerTransformSelector.baseName = "EmPointerGtruthToOpPointer"
        self.outputEmPointerGtruthToOpPointerTransformSelector.setMRMLScene(
            slicer.mrmlScene)
        self.outputEmPointerGtruthToOpPointerTransformSelector.setToolTip(
            "Select the transform to output the EmPointerGtruthToOpPointer calibration result to"
        )
        parametersFormLayout.addRow(
            self.outputEmPointerGtruthToOpPointerTransformSelectorLabel,
            self.outputEmPointerGtruthToOpPointerTransformSelector)

        # Select defaults (to make debugging easier)
        opPointerToOpRefNode = slicer.util.getNode('OpPointerToOpRef')
        if opPointerToOpRefNode:
            self.opticalPointerSelector.setCurrentNode(opPointerToOpRefNode)
        emPointerToEmTrackerNode = slicer.util.getNode('EmPointerToEmTracker')
        if emPointerToEmTrackerNode:
            self.emPointerSelector.setCurrentNode(emPointerToEmTrackerNode)
        emTrackerToOpRefInitialNode = slicer.util.getNode(
            'EmTrackerToOpRefInitial')
        if emTrackerToOpRefInitialNode:
            self.initialEmTrackerToOpRefSelector.setCurrentNode(
                emTrackerToOpRefInitialNode)
        emTrackerToOpRefOutputNode = slicer.util.getNode('EmTrackerToOpRef')
        if emTrackerToOpRefOutputNode:
            self.outputEmTrackerToOpRefTransformSelector.setCurrentNode(
                emTrackerToOpRefOutputNode)
        emPointerGtruthToOpPointerOutputNode = slicer.util.getNode(
            'EmPointerGtruthToOpPointer')
        if emPointerGtruthToOpPointerOutputNode:
            self.outputEmPointerGtruthToOpPointerTransformSelector.setCurrentNode(
                emPointerGtruthToOpPointerOutputNode)

        #
        # Controls Area
        #
        controlsCollapsibleButton = ctk.ctkCollapsibleButton()
        controlsCollapsibleButton.text = "Controls"
        self.layout.addWidget(controlsCollapsibleButton)

        # Layout within the dummy collapsible button
        controlsFormLayout = qt.QFormLayout(controlsCollapsibleButton)

        #
        # Number of data points to be collected input
        #

        self.numberDataPointsInputLabel = qt.QLabel()
        self.numberDataPointsInputLabel.setText(
            "Number of Collected Data Points:")
        self.numberDataPointsInput = qt.QSpinBox()
        self.numberDataPointsInput.maximum = 5000
        self.numberDataPointsInput.minimum = 10
        self.numberDataPointsInputLabel.setToolTip(
            "Select how many sample points will be used in calculations")
        controlsFormLayout.addRow(self.numberDataPointsInputLabel,
                                  self.numberDataPointsInput)
        #self.numberDataPoints = self.numberDataPointsInput.value

        #
        # Delay spinbox
        #
        self.delaySelectorLabel = qt.QLabel()
        self.delaySelectorLabel.setText("Delay (seconds):")
        self.delaySelector = qt.QSpinBox()
        self.delaySelector.minimum = 1
        self.delaySelector.maximum = 10
        self.delaySelector.value = 5
        self.delaySelector.setToolTip(
            "Time to wait before starting data collection after clicking 'Start data collection' button"
        )
        controlsFormLayout.addRow(self.delaySelectorLabel, self.delaySelector)

        #
        # Start data collection button
        #
        self.startButton = qt.QPushButton("Start data collection")
        self.startButton.toolTip = "Start collecting data that will be used in calculations"
        self.startButton.enabled = True
        self.startButton.connect('clicked(bool)', self.onStartDataCollection)
        controlsFormLayout.addRow(self.startButton)

        #
        # Delay countdown timer
        #
        self.delayTimer = qt.QTimer()
        self.delayTimerLabel = qt.QLabel()
        self.delayTimer.setInterval(1000)  # 1 second
        self.delayTimer.setSingleShot(True)
        self.delayTimer.connect('timeout()', self.onDelayTimerTimeout)
        controlsFormLayout.addRow(self.delayTimerLabel)

        #
        # Data collection progress bar
        #
        self.collectionProgressBar = qt.QProgressBar()
        self.collectionProgressBar.setRange(0, 100)
        self.collectionProgressBar.setVisible(False)
        controlsFormLayout.addRow(self.collectionProgressBar)

        #
        # Display Area
        #
        displayCollapsibleButton = ctk.ctkCollapsibleButton()
        displayCollapsibleButton.text = "Calibration results"
        self.layout.addWidget(displayCollapsibleButton)

        # Layout within the dummy collapsible button
        displayFormLayout = qt.QFormLayout(displayCollapsibleButton)

        #
        # Error metrics
        #
        self.transErrorLabel = qt.QLabel("Position error: N/A")
        self.rotErrorLabel = qt.QLabel("Orientation error: N/A")
        displayFormLayout.addRow(self.transErrorLabel)
        displayFormLayout.addRow(self.rotErrorLabel)

        # Add vertical spacer
        self.layout.addStretch(1)