Example #1
2
  def __init__(self, parent):
    self.vLayout = qt.QVBoxLayout(parent)
    self.formLayout = qt.QFormLayout()

    self.componentName = qt.QLineEdit()
    self.formLayout.addRow("Name:", self.componentName)

    self.componentNameValidator = qt.QRegExpValidator(
        qt.QRegExp(r"^[a-zA-Z_][a-zA-Z0-9_]*$"))
    self.componentName.setValidator(self.componentNameValidator)

    self.componentType = qt.QComboBox()
    self.formLayout.addRow("Type:", self.componentType)

    self.destination = ctk.ctkPathLineEdit()
    self.destination.filters = ctk.ctkPathLineEdit.Dirs
    self.formLayout.addRow("Destination:", self.destination)

    self.vLayout.addLayout(self.formLayout)
    self.vLayout.addStretch(1)

    self.buttonBox = qt.QDialogButtonBox()
    self.buttonBox.setStandardButtons(qt.QDialogButtonBox.Ok |
                                      qt.QDialogButtonBox.Cancel)
    self.vLayout.addWidget(self.buttonBox)
Example #2
1
  def setup(self):
    ScriptedLoadableModuleWidget.setup(self)

    self.logic = ScreenCaptureLogic()
    self.logic.logCallback = self.addLog
    self.viewNodeType = None
    self.animationMode = None
    self.createdOutputFile = None

    self.snapshotIndex = 0 # this counter is used for determining file names for single-image snapshots
    self.snapshotOutputDir = None
    self.snapshotFileNamePattern = None

    # Instantiate and connect widgets ...

    #
    # Input area
    #
    self.inputCollapsibleButton = ctk.ctkCollapsibleButton()
    self.inputCollapsibleButton.text = "Input"
    self.layout.addWidget(self.inputCollapsibleButton)
    inputFormLayout = qt.QFormLayout(self.inputCollapsibleButton)

    # Input view selector
    self.viewNodeSelector = slicer.qMRMLNodeComboBox()
    self.viewNodeSelector.nodeTypes = ["vtkMRMLSliceNode", "vtkMRMLViewNode"]
    self.viewNodeSelector.addEnabled = False
    self.viewNodeSelector.removeEnabled = False
    self.viewNodeSelector.noneEnabled = False
    self.viewNodeSelector.showHidden = False
    self.viewNodeSelector.showChildNodeTypes = False
    self.viewNodeSelector.setMRMLScene( slicer.mrmlScene )
    self.viewNodeSelector.setToolTip("This slice or 3D view will be updated during capture."
      "Only this view will be captured unless 'Capture of all views' option in output section is enabled." )
    inputFormLayout.addRow("Master view: ", self.viewNodeSelector)

    # Mode
    self.animationModeWidget = qt.QComboBox()
    self.animationModeWidget.setToolTip("Select the property that will be adjusted")
    inputFormLayout.addRow("Animation mode:", self.animationModeWidget)

    # Slice start offset position
    self.sliceStartOffsetSliderLabel = qt.QLabel("Start sweep offset:")
    self.sliceStartOffsetSliderWidget = ctk.ctkSliderWidget()
    self.sliceStartOffsetSliderWidget.singleStep = 30
    self.sliceStartOffsetSliderWidget.minimum = -100
    self.sliceStartOffsetSliderWidget.maximum = 100
    self.sliceStartOffsetSliderWidget.value = 0
    self.sliceStartOffsetSliderWidget.setToolTip("Start slice sweep offset.")
    inputFormLayout.addRow(self.sliceStartOffsetSliderLabel, self.sliceStartOffsetSliderWidget)

    # Slice end offset position
    self.sliceEndOffsetSliderLabel = qt.QLabel("End sweep offset:")
    self.sliceEndOffsetSliderWidget = ctk.ctkSliderWidget()
    self.sliceEndOffsetSliderWidget.singleStep = 5
    self.sliceEndOffsetSliderWidget.minimum = -100
    self.sliceEndOffsetSliderWidget.maximum = 100
    self.sliceEndOffsetSliderWidget.value = 0
    self.sliceEndOffsetSliderWidget.setToolTip("End slice sweep offset.")
    inputFormLayout.addRow(self.sliceEndOffsetSliderLabel, self.sliceEndOffsetSliderWidget)

    # 3D rotation range
    self.rotationSliderLabel = qt.QLabel("Rotation range:")
    self.rotationSliderWidget = ctk.ctkRangeWidget()
    self.rotationSliderWidget.singleStep = 5
    self.rotationSliderWidget.minimum = -180
    self.rotationSliderWidget.maximum = 180
    self.rotationSliderWidget.minimumValue = -180
    self.rotationSliderWidget.maximumValue = 180
    self.rotationSliderWidget.setToolTip("View rotation range, relative to current view orientation.")
    inputFormLayout.addRow(self.rotationSliderLabel, self.rotationSliderWidget)

    # 3D rotation axis
    self.rotationAxisLabel = qt.QLabel("Rotation axis:")
    self.rotationAxisWidget = ctk.ctkRangeWidget()
    self.rotationAxisWidget = qt.QComboBox()
    self.rotationAxisWidget.addItem("Yaw", AXIS_YAW)
    self.rotationAxisWidget.addItem("Pitch", AXIS_PITCH)
    inputFormLayout.addRow(self.rotationAxisLabel, self.rotationAxisWidget)


    # Sequence browser node selector
    self.sequenceBrowserNodeSelectorLabel = qt.QLabel("Sequence:")
    self.sequenceBrowserNodeSelectorWidget = slicer.qMRMLNodeComboBox()
    self.sequenceBrowserNodeSelectorWidget.nodeTypes = ["vtkMRMLSequenceBrowserNode"]
    self.sequenceBrowserNodeSelectorWidget.addEnabled = False
    self.sequenceBrowserNodeSelectorWidget.removeEnabled = False
    self.sequenceBrowserNodeSelectorWidget.noneEnabled = False
    self.sequenceBrowserNodeSelectorWidget.showHidden = False
    self.sequenceBrowserNodeSelectorWidget.setMRMLScene( slicer.mrmlScene )
    self.sequenceBrowserNodeSelectorWidget.setToolTip( "Items defined by this sequence browser will be replayed." )
    inputFormLayout.addRow(self.sequenceBrowserNodeSelectorLabel, self.sequenceBrowserNodeSelectorWidget)

    # Sequence start index
    self.sequenceStartItemIndexLabel = qt.QLabel("Start index:")
    self.sequenceStartItemIndexWidget = ctk.ctkSliderWidget()
    self.sequenceStartItemIndexWidget.minimum = 0
    self.sequenceStartItemIndexWidget.decimals = 0
    self.sequenceStartItemIndexWidget.setToolTip("First item in the sequence to capture.")
    inputFormLayout.addRow(self.sequenceStartItemIndexLabel, self.sequenceStartItemIndexWidget)

    # Sequence end index
    self.sequenceEndItemIndexLabel = qt.QLabel("End index:")
    self.sequenceEndItemIndexWidget = ctk.ctkSliderWidget()
    self.sequenceEndItemIndexWidget.minimum = 0
    self.sequenceEndItemIndexWidget.decimals = 0
    self.sequenceEndItemIndexWidget.setToolTip("Last item in the sequence to capture.")
    inputFormLayout.addRow(self.sequenceEndItemIndexLabel, self.sequenceEndItemIndexWidget)

    #
    # Output area
    #
    self.outputCollapsibleButton = ctk.ctkCollapsibleButton()
    self.outputCollapsibleButton.text = "Output"
    self.layout.addWidget(self.outputCollapsibleButton)
    outputFormLayout = qt.QFormLayout(self.outputCollapsibleButton)

    # Number of steps value
    self.numberOfStepsSliderWidget = ctk.ctkSliderWidget()
    self.numberOfStepsSliderWidget.singleStep = 10
    self.numberOfStepsSliderWidget.minimum = 1
    self.numberOfStepsSliderWidget.maximum = 600
    self.numberOfStepsSliderWidget.value = 31
    self.numberOfStepsSliderWidget.decimals = 0
    self.numberOfStepsSliderWidget.setToolTip("Number of images extracted between start and stop positions.")

    # Single step toggle button
    self.singleStepButton = qt.QToolButton()
    self.singleStepButton.setText("single")
    self.singleStepButton.setCheckable(True)
    self.singleStepButton.toolTip = "Capture a single image of current state only.\n" + \
      "New filename is generated for each captured image (no files are overwritten)."

    hbox = qt.QHBoxLayout()
    hbox.addWidget(self.singleStepButton)
    hbox.addWidget(self.numberOfStepsSliderWidget)
    outputFormLayout.addRow("Number of images:", hbox)

    # Output directory selector
    self.outputDirSelector = ctk.ctkPathLineEdit()
    self.outputDirSelector.filters = ctk.ctkPathLineEdit.Dirs
    self.outputDirSelector.settingKey = 'ScreenCaptureOutputDir'
    outputFormLayout.addRow("Output directory:", self.outputDirSelector)
    if not self.outputDirSelector.currentPath:
      defaultOutputPath = os.path.abspath(os.path.join(slicer.app.defaultScenePath,'SlicerCapture'))
      self.outputDirSelector.setCurrentPath(defaultOutputPath)

    self.captureAllViewsCheckBox = qt.QCheckBox(" ")
    self.captureAllViewsCheckBox.checked = False
    self.captureAllViewsCheckBox.setToolTip("If checked, all views will be captured. If unchecked then only the selected view will be captured.")
    outputFormLayout.addRow("Capture all views:", self.captureAllViewsCheckBox)

    self.videoExportCheckBox = qt.QCheckBox(" ")
    self.videoExportCheckBox.checked = False
    self.videoExportCheckBox.setToolTip("If checked, exported images will be written as a video file."
      " Requires setting of ffmpeg executable path in Advanced section.")

    self.videoFormatWidget = qt.QComboBox()
    self.videoFormatWidget.enabled = False
    self.videoFormatWidget.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Preferred)
    for videoFormatPreset in self.logic.videoFormatPresets:
      self.videoFormatWidget.addItem(videoFormatPreset["name"])

    hbox = qt.QHBoxLayout()
    hbox.addWidget(self.videoExportCheckBox)
    hbox.addWidget(self.videoFormatWidget)
    outputFormLayout.addRow("Video export:", hbox)

    self.videoFileNameWidget = qt.QLineEdit()
    self.videoFileNameWidget.setToolTip("String that defines file name and type.")
    self.videoFileNameWidget.text = "SlicerCapture.avi"
    self.videoFileNameWidget.setEnabled(False)
    outputFormLayout.addRow("Video file name:", self.videoFileNameWidget)

    self.videoLengthSliderWidget = ctk.ctkSliderWidget()
    self.videoLengthSliderWidget.singleStep = 0.1
    self.videoLengthSliderWidget.minimum = 0.1
    self.videoLengthSliderWidget.maximum = 30
    self.videoLengthSliderWidget.value = 5
    self.videoLengthSliderWidget.suffix = "s"
    self.videoLengthSliderWidget.decimals = 1
    self.videoLengthSliderWidget.setToolTip("Length of the exported video in seconds (without backward steps and repeating).")
    self.videoLengthSliderWidget.setEnabled(False)
    outputFormLayout.addRow("Video length:", self.videoLengthSliderWidget)

    #
    # Advanced area
    #
    self.advancedCollapsibleButton = ctk.ctkCollapsibleButton()
    self.advancedCollapsibleButton.text = "Advanced"
    self.advancedCollapsibleButton.collapsed = True
    outputFormLayout.addRow(self.advancedCollapsibleButton)
    advancedFormLayout = qt.QFormLayout(self.advancedCollapsibleButton)

    self.forwardBackwardCheckBox = qt.QCheckBox(" ")
    self.forwardBackwardCheckBox.checked = False
    self.forwardBackwardCheckBox.setToolTip("If checked, image series will be generated playing forward and then backward.")
    advancedFormLayout.addRow("Forward-backward:", self.forwardBackwardCheckBox)

    self.repeatSliderWidget = ctk.ctkSliderWidget()
    self.repeatSliderWidget.decimals = 0
    self.repeatSliderWidget.singleStep = 1
    self.repeatSliderWidget.minimum = 1
    self.repeatSliderWidget.maximum = 50
    self.repeatSliderWidget.value = 1
    self.repeatSliderWidget.setToolTip("Number of times image series are repeated. Useful for making short videos longer for playback in software"
      " that does not support looped playback.")
    advancedFormLayout.addRow("Repeat:", self.repeatSliderWidget)

    ffmpegPath = self.logic.getFfmpegPath()
    self.ffmpegPathSelector = ctk.ctkPathLineEdit()
    self.ffmpegPathSelector.setCurrentPath(ffmpegPath)
    self.ffmpegPathSelector.nameFilters = [self.logic.getFfmpegExecutableFilename()]
    self.ffmpegPathSelector.setSizePolicy(qt.QSizePolicy.MinimumExpanding, qt.QSizePolicy.Preferred)
    self.ffmpegPathSelector.setToolTip("Set the path to ffmpeg executable. Download from: https://www.ffmpeg.org/")
    advancedFormLayout.addRow("ffmpeg executable:", self.ffmpegPathSelector)

    self.videoExportFfmpegWarning = qt.QLabel('<qt><b><font color="red">Set valid ffmpeg executable path! '+
      '<a href="http://wiki.slicer.org/slicerWiki/index.php/Documentation/Nightly/Modules/ScreenCapture#Setting_up_ffmpeg">Help...</a></font></b></qt>')
    self.videoExportFfmpegWarning.connect('linkActivated(QString)', self.openURL)
    self.videoExportFfmpegWarning.setVisible(False)
    advancedFormLayout.addRow("", self.videoExportFfmpegWarning)

    self.extraVideoOptionsWidget = qt.QLineEdit()
    self.extraVideoOptionsWidget.setToolTip('Additional video conversion options passed to ffmpeg. Parameters -i (input files), -y'
      +'(overwrite without asking), -r (frame rate), -start_number are specified by the module and therefore'
      +'should not be included in this list.')
    advancedFormLayout.addRow("Video extra options:", self.extraVideoOptionsWidget)

    self.fileNamePatternWidget = qt.QLineEdit()
    self.fileNamePatternWidget.setToolTip(
      "String that defines file name, type, and numbering scheme. Default: image%05d.png.")
    self.fileNamePatternWidget.text = "image_%05d.png"
    advancedFormLayout.addRow("Image file name pattern:", self.fileNamePatternWidget)

    self.maxFramesWidget = qt.QSpinBox()
    self.maxFramesWidget.setRange(1, 9999)
    self.maxFramesWidget.setValue(600)
    self.maxFramesWidget.setToolTip(
      "Maximum number of images to be captured (without backward steps and repeating).")
    advancedFormLayout.addRow("Maximum number of images:", self.maxFramesWidget)

    # Capture button
    self.captureButtonLabelCapture = "Capture"
    self.captureButtonLabelCancel = "Cancel"
    self.captureButton = qt.QPushButton(self.captureButtonLabelCapture)
    self.captureButton.toolTip = "Capture slice sweep to image sequence."
    self.showCreatedOutputFileButton = qt.QPushButton()
    self.showCreatedOutputFileButton.setIcon(qt.QIcon(':Icons/Go.png'))
    self.showCreatedOutputFileButton.setMaximumWidth(60)
    self.showCreatedOutputFileButton.enabled = False
    self.showCreatedOutputFileButton.toolTip = "Show created output file."
    hbox = qt.QHBoxLayout()
    hbox.addWidget(self.captureButton)
    hbox.addWidget(self.showCreatedOutputFileButton)
    self.layout.addLayout(hbox)

    self.statusLabel = qt.QPlainTextEdit()
    self.statusLabel.setTextInteractionFlags(qt.Qt.TextSelectableByMouse)
    self.statusLabel.setCenterOnScroll(True)
    self.layout.addWidget(self.statusLabel)

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

    # connections
    self.captureButton.connect('clicked(bool)', self.onCaptureButton)
    self.showCreatedOutputFileButton.connect('clicked(bool)', self.onShowCreatedOutputFile)
    self.viewNodeSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.updateViewOptions)
    self.animationModeWidget.connect("currentIndexChanged(int)", self.updateViewOptions)
    self.sliceStartOffsetSliderWidget.connect('valueChanged(double)', self.setSliceOffset)
    self.sliceEndOffsetSliderWidget.connect('valueChanged(double)', self.setSliceOffset)
    self.sequenceBrowserNodeSelectorWidget.connect("currentNodeChanged(vtkMRMLNode*)", self.updateViewOptions)
    self.sequenceStartItemIndexWidget.connect('valueChanged(double)', self.setSequenceItemIndex)
    self.sequenceEndItemIndexWidget.connect('valueChanged(double)', self.setSequenceItemIndex)
    self.videoExportCheckBox.connect('toggled(bool)', self.fileNamePatternWidget, 'setDisabled(bool)')
    self.videoExportCheckBox.connect('toggled(bool)', self.videoFileNameWidget, 'setEnabled(bool)')
    self.videoExportCheckBox.connect('toggled(bool)', self.videoLengthSliderWidget, 'setEnabled(bool)')
    self.videoExportCheckBox.connect('toggled(bool)', self.videoFormatWidget, 'setEnabled(bool)')
    self.videoFormatWidget.connect("currentIndexChanged(int)", self.updateVideoFormat)
    self.singleStepButton.connect('toggled(bool)', self.numberOfStepsSliderWidget, 'setDisabled(bool)')
    self.maxFramesWidget.connect('valueChanged(int)', self.maxFramesChanged)

    self.updateVideoFormat(0)
    self.updateViewOptions()
Example #3
0
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        # Instantiate and connect widgets ...

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

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

        #
        # Select landmark file to import
        #
        self.inputFileSelector = ctk.ctkPathLineEdit()
        self.inputFileSelector.filters = ctk.ctkPathLineEdit().Files
        self.inputFileSelector.setToolTip(
            "Select surface image that will be imported as a segment for editing"
        )
        parametersFormLayout.addRow("Select surface file to edit:",
                                    self.inputFileSelector)

        #
        # check box to trigger taking screen shots for later use in tutorials
        #
        self.enableScreenshotsFlagCheckBox = qt.QCheckBox()
        self.enableScreenshotsFlagCheckBox.checked = 0
        self.enableScreenshotsFlagCheckBox.setToolTip(
            "If checked, take screen shots for tutorials. Use Save Data to write them to disk."
        )
        parametersFormLayout.addRow("Enable Screenshots",
                                    self.enableScreenshotsFlagCheckBox)

        #
        # Apply Button
        #
        self.applyButton = qt.QPushButton("Apply")
        self.applyButton.toolTip = "Run the conversion."
        self.applyButton.enabled = False
        parametersFormLayout.addRow(self.applyButton)

        # connections
        self.applyButton.connect('clicked(bool)', self.onApplyButton)
        self.inputFileSelector.connect('validInputChanged(bool)',
                                       self.onSelectInput)

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

        # Refresh Apply button state
        self.onSelectInput()
  def __init__(self, parent):
    self.vLayout = qt.QVBoxLayout(parent)
    self.formLayout = qt.QFormLayout()

    self.componentName = qt.QLineEdit()
    self.formLayout.addRow("Name:", self.componentName)

    self.componentNameValidator = qt.QRegExpValidator(
        qt.QRegExp(r"^[a-zA-Z_][a-zA-Z0-9_]*$"))
    self.componentName.setValidator(self.componentNameValidator)

    self.componentType = qt.QComboBox()
    self.formLayout.addRow("Type:", self.componentType)

    self.destination = ctk.ctkPathLineEdit()
    self.destination.filters = ctk.ctkPathLineEdit.Dirs
    self.formLayout.addRow("Destination:", self.destination)

    self.vLayout.addLayout(self.formLayout)
    self.vLayout.addStretch(1)

    self.buttonBox = qt.QDialogButtonBox()
    self.buttonBox.setStandardButtons(qt.QDialogButtonBox.Ok |
                                      qt.QDialogButtonBox.Cancel)
    self.vLayout.addWidget(self.buttonBox)
    def createUserInterface(self):
        layout = qt.QFormLayout(self)
        layout.setVerticalSpacing(5)

        loadCaseGroupBox = qt.QGroupBox()
        loadCaseGroupBox.title = "Load Volume"
        loadCaseGroupBox.setToolTip("Select the volume to load.")

        loadCaseFormLayout = qt.QFormLayout(loadCaseGroupBox)
        loadCaseFormLayout.setContentsMargins(10, 10, 10, 10)

        self.loadCaseSelector = ctk.ctkPathLineEdit()
        self.loadCaseSelector.filters = ctk.ctkPathLineEdit.Files
        loadCaseFormLayout.addRow("NRRD Volume:", self.loadCaseSelector)
        self.loadCaseSelector.connect('currentPathChanged(const QString)',
                                      self.loadSavedCase)
        layout.addWidget(loadCaseGroupBox)

        activeVolumeGroupBox = qt.QGroupBox()
        activeVolumeGroupBox.title = "Active Volume Data"
        layout.addWidget(activeVolumeGroupBox)
        activeVolumeFormLayout = qt.QFormLayout(activeVolumeGroupBox)
        activeVolumeFormLayout.setContentsMargins(10, 10, 10, 10)

        self.__inputSelector = slicer.qMRMLNodeComboBox()
        self.__inputSelector.nodeTypes = (("vtkMRMLScalarVolumeNode"), "")
        self.__inputSelector.addEnabled = False
        self.__inputSelector.removeEnabled = False
        self.__inputSelector.setMRMLScene(slicer.mrmlScene)
        activeVolumeFormLayout.addRow(self.__inputSelector)
        qt.QTimer.singleShot(0, self.killButton)
Example #6
0
  def setup(self):
    ScriptedLoadableModuleWidget.setup(self)

    # Instantiate and connect widgets ...

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

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

    #
    # Select landmark file to import
    #
    self.inputFileSelector = ctk.ctkPathLineEdit()
    self.inputFileSelector.setToolTip( "Select landmark file for import" )
    parametersFormLayout.addRow("Select file containing landmark names and coordinates to load:", self.inputFileSelector)
    
    #
    # Get header length
    #
    self.headerLengthWidget = ctk.ctkDoubleSpinBox()
    self.headerLengthWidget.value = 2
    self.headerLengthWidget.minimum = 0
    self.headerLengthWidget.singleStep = 1
    self.headerLengthWidget.setToolTip("Input the number of lines in header")
    parametersFormLayout.addRow("Header length:", self.headerLengthWidget)

    #
    # check box to trigger taking screen shots for later use in tutorials
    #
    self.enableScreenshotsFlagCheckBox = qt.QCheckBox()
    self.enableScreenshotsFlagCheckBox.checked = 0
    self.enableScreenshotsFlagCheckBox.setToolTip("If checked, take screen shots for tutorials. Use Save Data to write them to disk.")
    parametersFormLayout.addRow("Enable Screenshots", self.enableScreenshotsFlagCheckBox)

    #
    # Apply Button
    #
    self.applyButton = qt.QPushButton("Apply")
    self.applyButton.toolTip = "Run the algorithm."
    self.applyButton.enabled = False
    parametersFormLayout.addRow(self.applyButton)

    # connections
    self.applyButton.connect('clicked(bool)', self.onApplyButton)
    self.inputFileSelector.connect('validInputChanged(bool)', self.onSelect)
    

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

    # Refresh Apply button state
    self.onSelect()
Example #7
0
  def setup(self):
    ScriptedLoadableModuleWidget.setup(self)

    # Instantiate and connect widgets ...

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

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

    self.inputDirectory=ctk.ctkPathLineEdit()
    self.inputDirectory.filters=ctk.ctkPathLineEdit.Dirs
    self.inputDirectory.setToolTip( "Select input directory" )
    parametersFormLayout.addRow("Input folder:", self.inputDirectory)

    self.outputDirectory=ctk.ctkPathLineEdit()
    self.outputDirectory.filters=ctk.ctkPathLineEdit.Dirs
    self.outputDirectory.setToolTip( "Select output directory")
    parametersFormLayout.addRow("Output folder: ", self.outputDirectory)


    #
    # Apply Button
    #
    self.applyButton = qt.QPushButton("Apply")
    self.applyButton.toolTip = "Convert."
    self.applyButton.enabled = False
    parametersFormLayout.addRow(self.applyButton)

    # connections
    self.inputDirectory.connect('validInputChanged(bool)', self.onSelect)
    self.outputDirectory.connect('validInputChanged(bool)', self.onSelect)
    self.applyButton.connect('clicked(bool)', self.onApplyButton)

    # Add vertical spacer
    self.layout.addStretch(1)
Example #8
0
  def setup(self):
    # Collapsible button
    ioCollapsible = ctk.ctkCollapsibleButton()
    ioCollapsible.text = "Input and Output Selection"
    self.layout.addWidget(ioCollapsible)

    # Layout within the sample collapsible button
    ioFormLayout = qt.QFormLayout(ioCollapsible)
       
    # input directory selection
    self.inputDirSelector = ctk.ctkPathLineEdit()
    self.inputDirSelector.filters = ctk.ctkPathLineEdit.Dirs
    self.inputDirSelector.options = ctk.ctkPathLineEdit.ShowDirsOnly
    self.inputDirSelector.settingKey = 'inputDir'
    ioFormLayout.addRow("Input Directory:", self.inputDirSelector)
       
    # output directory selection
    self.outputDirSelector = ctk.ctkPathLineEdit()
    self.outputDirSelector.filters = ctk.ctkPathLineEdit.Dirs
    self.outputDirSelector.options = ctk.ctkPathLineEdit.ShowDirsOnly
    self.outputDirSelector.settingKey = 'outputDir'
    ioFormLayout.addRow("Empty Output Directory:", self.outputDirSelector)
     
    # transform file selection
    self.transformationSelector = ctk.ctkPathLineEdit()
    self.transformationSelector.filters = ctk.ctkPathLineEdit.Files
    self.transformationSelector.settingKey = 'transformationFile'
    ioFormLayout.addRow("Transform file:", self.transformationSelector)
       
    # button to run
    runTransformButton = qt.QPushButton("Harden Transform") 
    runTransformButton.toolTip = "Harden models in selected directory and save to output directory." 
    ioFormLayout.addWidget(runTransformButton)
    runTransformButton.connect('clicked(bool)', self.onrunTransformButtonClicked) 

    # Set local var as instance attribute
    self.runTransformButton = runTransformButton
Example #9
0
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        # Instantiate and connect widgets ...

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

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

        #
        # input directory selector
        #
        with It(ctk.ctkPathLineEdit()) as w:
            self.inputDirectorySelector = w
            # make a directory-only, save dialog
            w.filters = ctk.ctkPathLineEdit.Dirs | ctk.ctkPathLineEdit.Writable
            parametersFormLayout.addRow("Input Directory: ", w)

        #
        # Apply Button
        #
        with It(qt.QPushButton("Apply")) as w:
            self.applyButton = w
            w.toolTip = "Run the algorithm."
            w.enabled = False
            parametersFormLayout.addRow(w)

        # connections
        self.applyButton.connect('clicked(bool)', self.onApplyButton)
        self.inputDirectorySelector.connect(
            'currentPathChanged(const QString&)', self.reset)

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

        # Refresh Apply button state
        self.onSelect()
    def makeGUI(self):
        self.setDirButton = ctk.ctkCollapsibleButton()
        self.setDirButton.text = 'Select dataset directory'
        setDirLayout = qt.QFormLayout(self.setDirButton)
        self.layout.addWidget(self.setDirButton)

        self.datasetDirEdit = ctk.ctkPathLineEdit()
        self.datasetDirEdit.filters = ctk.ctkPathLineEdit.Dirs
        setDirLayout.addRow('EPISURG directory: ', self.datasetDirEdit)

        self.datasetDirButton = qt.QPushButton('Load subjects')
        self.datasetDirButton.clicked.connect(self.onLoadSubjectsButton)
        setDirLayout.addWidget(self.datasetDirButton)

        self.downloadDatasetButton = qt.QPushButton('Download dataset')
        self.downloadDatasetButton.clicked.connect(
            self.onDownloadDatasetButton)
        setDirLayout.addWidget(self.downloadDatasetButton)

        self.subjectsButton = ctk.ctkCollapsibleButton()
        self.subjectsButton.text = 'Select subject to load'
        self.subjectsButton.setEnabled(False)
        subjectsLayout = qt.QFormLayout(self.subjectsButton)
        self.layout.addWidget(self.subjectsButton)

        self.subjectsComboBox = qt.QComboBox()
        self.subjectsComboBox.addItem('Select subject ID')
        self.subjectsComboBox.currentIndexChanged.connect(
            self.onSubjectsComboBox)
        subjectsLayout.addWidget(self.subjectsComboBox)

        self.previousSubjectPushButton = qt.QPushButton('Previous')
        self.previousSubjectPushButton.clicked.connect(
            self.onPreviousSubjectButton)
        subjectsLayout.addWidget(self.previousSubjectPushButton)

        self.nextSubjectPushButton = qt.QPushButton('Next')
        self.nextSubjectPushButton.clicked.connect(self.onNextSubjectButton)
        subjectsLayout.addWidget(self.nextSubjectPushButton)

        self.layout.addStretch()
Example #11
0
    def setup(self):
        self.setLayout(qt.QGridLayout())
        settingNames = self.getSettingNames()
        for index, setting in enumerate(settingNames):
            label = self.createLabel(setting)
            value = self.getSetting(setting)
            if value.lower() in ["true", "false"]:
                element = qt.QCheckBox()
                element.checked = value.lower() == "true"
            elif value.isdigit():
                element = qt.QSpinBox()
                element.value = int(value)
            elif os.path.exists(value):
                element = ctk.ctkPathLineEdit()
                if os.path.isdir(value):
                    element.filters = ctk.ctkPathLineEdit.Dirs
                else:
                    element.filters = ctk.ctkPathLineEdit.Files
                element.currentPath = value
            else:
                element = self.createLineEdit(value)
                element.minimumWidth = self.getMinimumTextWidth(
                    element.text) + 10

            self.layout().addWidget(label, index, 0)
            self.layout().addWidget(element, index, 1, 1,
                                    qt.QSizePolicy.ExpandFlag)
            self.keyElementPairs.append((label.text, element))

        self.okButton = self.createButton("OK")
        self.cancelButton = self.createButton("Cancel")

        self.addButton(self.okButton, qt.QMessageBox.AcceptRole)
        self.addButton(self.cancelButton, qt.QMessageBox.NoRole)

        self.layout().addWidget(
            self.createHLayout([self.okButton, self.cancelButton]),
            len(settingNames), 1)
        self.okButton.clicked.connect(self.onOkButtonClicked)
Example #12
0
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        # Instantiate and connect widgets ...

        #
        # File area
        #
        filesCollapsibleButton = ctk.ctkCollapsibleButton()
        filesCollapsibleButton.text = "Files"
        filesCollapsibleButton.collapsed = False
        self.layout.addWidget(filesCollapsibleButton)
        # Layout within the files collapsible button
        filesFormLayout = qt.QFormLayout(filesCollapsibleButton)

        self.fileModel = qt.QStandardItemModel()
        self.fileTable = qt.QTableView()
        self.fileTable.horizontalHeader().stretchLastSection = True
        self.fileTable.horizontalHeader().visible = False
        self.fileTable.setModel(self.fileModel)
        filesFormLayout.addRow(self.fileTable)

        buttonLayout = qt.QHBoxLayout()
        self.addByBrowsingButton = qt.QPushButton("Browse for files")
        self.clearFilesButton = qt.QPushButton("Clear files")
        buttonLayout.addWidget(self.addByBrowsingButton)
        buttonLayout.addWidget(self.clearFilesButton)
        filesFormLayout.addRow(buttonLayout)

        self.propertiesLabel = qt.QLabel()
        filesFormLayout.addRow(self.propertiesLabel)

        #
        # output area
        #
        outputCollapsibleButton = ctk.ctkCollapsibleButton()
        outputCollapsibleButton.text = "Output"
        outputCollapsibleButton.collapsed = False
        self.layout.addWidget(outputCollapsibleButton)
        outputFormLayout = qt.QFormLayout(outputCollapsibleButton)

        #
        # output volume selector
        #
        self.outputSelector = slicer.qMRMLNodeComboBox()

        self.outputSelector.nodeTypes = [
            "vtkMRMLScalarVolumeNode",
        ]

        self.outputSelector.showChildNodeTypes = False
        self.outputSelector.showHidden = False
        self.outputSelector.showChildNodeTypes = False
        self.outputSelector.selectNodeUponCreation = True
        self.outputSelector.noneEnabled = True
        self.outputSelector.removeEnabled = True
        self.outputSelector.renameEnabled = True
        self.outputSelector.addEnabled = True
        self.outputSelector.setMRMLScene(slicer.mrmlScene)
        self.outputSelector.setToolTip(
            "Pick the output volume to populate or None to autogenerate.")
        outputFormLayout.addRow("Output Volume: ", self.outputSelector)

        self.spacing = ctk.ctkCoordinatesWidget()
        self.spacing.decimals = 8
        self.spacing.coordinates = "1,1,1"
        self.spacing.toolTip = "Set the colunm, row, slice spacing in mm; original spacing not including downsample"
        outputFormLayout.addRow("Spacing: ", self.spacing)

        self.downsample = qt.QCheckBox()
        self.downsample.toolTip = "Reduces data size by half in each dimension by skipping every other pixel and slice (uses about 1/8 memory)"
        outputFormLayout.addRow("Downsample: ", self.downsample)

        self.reverse = qt.QCheckBox()
        self.reverse.toolTip = "Read the images in reverse order"
        outputFormLayout.addRow("Reverse: ", self.reverse)

        self.sliceSkip = ctk.ctkDoubleSpinBox()
        self.sliceSkip.decimals = 0
        self.sliceSkip.minimum = 0
        self.sliceSkip.toolTip = "Skips the selected number of slices (use, for example, on long thin samples with more slices than in-plane resolution)"
        outputFormLayout.addRow("Slice skip: ", self.sliceSkip)

        self.loadButton = qt.QPushButton("Load files")
        outputFormLayout.addRow(self.loadButton)

        #
        # Add by name area
        #
        addByNameCollapsibleButton = ctk.ctkCollapsibleButton()
        addByNameCollapsibleButton.text = "Add files by name"
        addByNameCollapsibleButton.collapsed = True
        addByNameFormLayout = qt.QFormLayout(addByNameCollapsibleButton)
        # Don't enable Add by name for now - let's see if it's actually needed
        # self.layout.addWidget(addByNameCollapsibleButton)

        forExample = """
    directoryPath = '/Volumes/SSD2T/data/SlicerMorph/Sample_for_steve/1326_Rec'
    pathFormat = '%s/1326__rec%04d.png'
    start, end =  (50, 621)
    """

        self.archetypePathEdit = ctk.ctkPathLineEdit()
        addByNameFormLayout.addRow("Archetype file", self.archetypePathEdit)

        self.archetypeFormat = qt.QLineEdit()
        addByNameFormLayout.addRow("Name format", self.archetypeFormat)

        self.indexRange = ctk.ctkRangeWidget()
        self.indexRange.decimals = 0
        self.indexRange.maximum = 0
        addByNameFormLayout.addRow("Index range", self.indexRange)

        self.generateNamesButton = qt.QPushButton("Apply")
        self.generateNamesButton.toolTip = "Run the algorithm."
        self.generateNamesButton.enabled = False
        addByNameFormLayout.addRow(self.generateNamesButton)

        # connections
        self.addByBrowsingButton.connect('clicked()', self.addByBrowsing)
        self.clearFilesButton.connect('clicked()', self.onClearFiles)
        self.archetypePathEdit.connect('currentPathChanged(QString)',
                                       self.validateInput)
        self.archetypePathEdit.connect('currentPathChanged(QString)',
                                       self.updateGUIFromArchetype)
        self.archetypeFormat.connect('textChanged(QString)',
                                     self.validateInput)
        self.generateNamesButton.connect('clicked()', self.onGenerateNames)
        # self.outputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.validateInput) # TODO - this is missing
        self.loadButton.connect('clicked()', self.onLoadButton)

        # refill last selection
        self.archetypePathEdit.currentPath = slicer.util.settingsValue(
            "ImageStacks/lastArchetypePath", "")

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

        # Refresh Apply button state
        self.validateInput()
  def setup(self):
    self.CsvInputGroupBox = qt.QGroupBox('CSV input for local files')

    CsvInputLayout = qt.QFormLayout(self.CsvInputGroupBox)

    #
    # Input CSV Path
    #
    self.batchTableSelector = slicer.qMRMLNodeComboBox()
    self.batchTableSelector.nodeTypes = ['vtkMRMLTableNode']
    self.batchTableSelector.addEnabled = True
    self.batchTableSelector.selectNodeUponCreation = True
    self.batchTableSelector.renameEnabled = True
    self.batchTableSelector.removeEnabled = True
    self.batchTableSelector.noneEnabled = False
    self.batchTableSelector.setMRMLScene(slicer.mrmlScene)
    self.batchTableSelector.toolTip = 'Select the table representing the cases to process.'
    CsvInputLayout.addRow(self.batchTableSelector)

    #
    # Parameters Area
    #
    self.parametersCollapsibleButton = ctk.ctkCollapsibleButton()
    self.parametersCollapsibleButton.text = 'Table view and attribute properties'
    CsvInputLayout.addWidget(self.parametersCollapsibleButton)

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

    self.batchTableView = slicer.qMRMLTableView()
    parametersFormLayout.addRow(self.batchTableView)
    self.batchTableView.show()

    #
    # Input parameters GroupBox
    #
    self.inputParametersGroupBox = qt.QGroupBox('Input parameters')
    parametersFormLayout.addRow(self.inputParametersGroupBox)

    inputParametersFormLayout = qt.QFormLayout(self.inputParametersGroupBox)

    #
    # Root Path
    #
    self.rootSelector = qt.QLineEdit()
    self.rootSelector.text = 'path'
    self.rootSelector.toolTip = 'Location of the root directory to load from, or the column name specifying said ' \
                                'directory in the input CSV'
    inputParametersFormLayout.addRow('Root Column', self.rootSelector)

    #
    # Image Path
    #
    self.imageSelector = qt.QLineEdit()
    self.imageSelector.text = 'image'
    self.imageSelector.toolTip = 'Name of the column specifying main image files in input CSV'
    inputParametersFormLayout.addRow('Image Column', self.imageSelector)

    #
    # GroundTruth masks
    #
    self.inputGTMaskColumnNames = qt.QLineEdit()
    self.inputGTMaskColumnNames.text = 'gt_0,gt_1,gt_2'
    self.inputGTMaskColumnNames.toolTip = 'Comma separated names of the columns specifying groundtruth mask files in input CSV'
    inputParametersFormLayout.addRow('Groundtruth masks Column(s)', self.inputGTMaskColumnNames)

    #
    # Predicted masks
    #
    self.inputPredMaskColumnNames = qt.QLineEdit()
    self.inputPredMaskColumnNames.text = 'pred_0,pred_1,pred_2'
    self.inputPredMaskColumnNames.toolTip = 'Comma separated names of the columns specifying predicted mask files in input CSV'
    inputParametersFormLayout.addRow('Predicted masks Column(s)', self.inputPredMaskColumnNames)

    self.iterationParametersGroupBox = qt.QGroupBox('Iteration parameters')
    parametersFormLayout.addRow(self.iterationParametersGroupBox)

    iterationParametersFormLayout = qt.QFormLayout(self.iterationParametersGroupBox)

    #
    # Cache Cases
    #
    self.cacheCases = qt.QCheckBox()
    self.cacheCases.checked = True
    self.cacheCases.toolTip = 'Cache cases for faster reload'
    iterationParametersFormLayout.addRow('Cache cases', self.cacheCases)

    #
    # Preload Cases
    #
    self.preloadCases = qt.QCheckBox()
    self.preloadCases.checked = False
    self.preloadCases.toolTip = 'Preloading all cases'
    iterationParametersFormLayout.addRow('Preload cases', self.preloadCases)

    #
    # Output Case Table Directory
    #
    self.tableOutputDirectory = ctk.ctkPathLineEdit()
    self.tableOutputDirectory.filters = ctk.ctkPathLineEdit.Dirs
    iterationParametersFormLayout.addRow('Case tables output dir', self.tableOutputDirectory)

    #
    # Progressbar
    #
    self.progressBar = qt.QProgressBar()
    self.progressBar.setFormat("%v/%m")
    self.progressBar.visible = False
    iterationParametersFormLayout.addWidget(self.progressBar)

    #
    # Connect Event Handlers
    #
    self.batchTableSelector.connect('nodeActivated(vtkMRMLNode*)', self.onChangeTable)
    self.imageSelector.connect('textEdited(QString)', self.onChangeImageColumn)
    self.preloadCases.stateChanged.connect(self.onPreloadCasesChanged)

    return self.CsvInputGroupBox
  def setup(self):
    ScriptedLoadableModuleWidget.setup(self)

    self.logic = ScreenCaptureLogic()
    self.logic.logCallback = self.addLog

    # Instantiate and connect widgets ...

    #
    # Input area
    #
    inputCollapsibleButton = ctk.ctkCollapsibleButton()
    inputCollapsibleButton.text = "Input"
    self.layout.addWidget(inputCollapsibleButton)
    inputFormLayout = qt.QFormLayout(inputCollapsibleButton)

    # Input view selector
    self.viewNodeSelector = slicer.qMRMLNodeComboBox()
    self.viewNodeSelector.nodeTypes = ["vtkMRMLSliceNode", "vtkMRMLViewNode"]
    self.viewNodeSelector.addEnabled = False
    self.viewNodeSelector.removeEnabled = False
    self.viewNodeSelector.noneEnabled = False
    self.viewNodeSelector.showHidden = False
    self.viewNodeSelector.showChildNodeTypes = False
    self.viewNodeSelector.setMRMLScene( slicer.mrmlScene )
    self.viewNodeSelector.setToolTip( "Contents of this slice or 3D view will be captured." )
    inputFormLayout.addRow("View to capture: ", self.viewNodeSelector)

    #
    # Slice view options area
    #
    self.sliceViewOptionsCollapsibleButton = ctk.ctkCollapsibleButton()
    self.sliceViewOptionsCollapsibleButton.text = "Slice viewer sweep"
    self.layout.addWidget(self.sliceViewOptionsCollapsibleButton)
    sliceViewOptionsLayout = qt.QFormLayout(self.sliceViewOptionsCollapsibleButton)

    # Start slice offset position
    self.startSliceOffsetSliderWidget = ctk.ctkSliderWidget()
    self.startSliceOffsetSliderWidget.singleStep = 30
    self.startSliceOffsetSliderWidget.minimum = -100
    self.startSliceOffsetSliderWidget.maximum = 100
    self.startSliceOffsetSliderWidget.value = 0
    self.startSliceOffsetSliderWidget.setToolTip("Start slice offset.")
    sliceViewOptionsLayout.addRow("Start offset:", self.startSliceOffsetSliderWidget)

    # End slice offset position
    self.endSliceOffsetSliderWidget = ctk.ctkSliderWidget()
    self.endSliceOffsetSliderWidget.singleStep = 5
    self.endSliceOffsetSliderWidget.minimum = -100
    self.endSliceOffsetSliderWidget.maximum = 100
    self.endSliceOffsetSliderWidget.value = 0
    self.endSliceOffsetSliderWidget.setToolTip("End slice offset.")
    sliceViewOptionsLayout.addRow("End offset:", self.endSliceOffsetSliderWidget)

    #
    # 3D view options area
    #
    self.threeDViewOptionsCollapsibleButton = ctk.ctkCollapsibleButton()
    self.threeDViewOptionsCollapsibleButton.text = "3D view rotation"
    self.layout.addWidget(self.threeDViewOptionsCollapsibleButton)
    threeDViewOptionsLayout = qt.QFormLayout(self.threeDViewOptionsCollapsibleButton)

    # Start rotation
    self.startRotationSliderWidget = ctk.ctkSliderWidget()
    self.startRotationSliderWidget.singleStep = 5
    self.startRotationSliderWidget.minimum = 0
    self.startRotationSliderWidget.maximum = 180
    self.startRotationSliderWidget.value = 180
    self.startRotationSliderWidget.setToolTip("Rotation angle for the first image, relative to current orientation.")
    threeDViewOptionsLayout.addRow("Start rotation angle:", self.startRotationSliderWidget)

    # End rotation
    self.endRotationSliderWidget = ctk.ctkSliderWidget()
    self.endRotationSliderWidget.singleStep = 5
    self.endRotationSliderWidget.minimum = 0
    self.endRotationSliderWidget.maximum = 180
    self.endRotationSliderWidget.value = 180
    self.endRotationSliderWidget.setToolTip("Rotation angle for the last image, relative to current orientation.")
    threeDViewOptionsLayout.addRow("End rotation angle:", self.endRotationSliderWidget)

    #
    # Output area
    #
    outputCollapsibleButton = ctk.ctkCollapsibleButton()
    outputCollapsibleButton.text = "Output"
    self.layout.addWidget(outputCollapsibleButton)
    outputFormLayout = qt.QFormLayout(outputCollapsibleButton)
    
    # Number of steps value
    self.numberOfStepsSliderWidget = ctk.ctkSliderWidget()
    self.numberOfStepsSliderWidget.singleStep = 5
    self.numberOfStepsSliderWidget.minimum = 2
    self.numberOfStepsSliderWidget.maximum = 150
    self.numberOfStepsSliderWidget.value = 30
    self.numberOfStepsSliderWidget.decimals = 0
    self.numberOfStepsSliderWidget.setToolTip("Number of images extracted between start and stop positions.")
    outputFormLayout.addRow("Number of images:", self.numberOfStepsSliderWidget)

    # Output directory selector
    self.outputDirSelector = ctk.ctkPathLineEdit()
    self.outputDirSelector.filters = ctk.ctkPathLineEdit.Dirs
    self.outputDirSelector.settingKey = 'ScreenCaptureOutputDir'
    outputFormLayout.addRow("Output directory:", self.outputDirSelector)
    if not self.outputDirSelector.currentPath:
      defaultOutputPath = os.path.abspath(os.path.join(slicer.app.defaultScenePath,'SlicerCapture'))
      self.outputDirSelector.setCurrentPath(defaultOutputPath)

    self.videoExportCheckBox = qt.QCheckBox()
    self.videoExportCheckBox.checked = False
    self.videoExportCheckBox.setToolTip("If checked, exported images will be written as a video file.")
    outputFormLayout.addRow("Video export:", self.videoExportCheckBox)

    self.videoFileNameWidget = qt.QLineEdit()
    self.videoFileNameWidget.setToolTip("String that defines file name, type, and numbering scheme. Default: capture.avi.")
    self.videoFileNameWidget.text = "SlicerCapture.avi"
    self.videoFileNameWidget.setEnabled(False)
    outputFormLayout.addRow("Video file name:", self.videoFileNameWidget)

    self.videoQualitySliderWidget = ctk.ctkSliderWidget()
    self.videoQualitySliderWidget.singleStep = 0.1
    self.videoQualitySliderWidget.minimum = 0
    self.videoQualitySliderWidget.maximum = 20
    self.videoQualitySliderWidget.value = 2
    self.videoQualitySliderWidget.decimals = 1
    self.videoQualitySliderWidget.setToolTip("Bit-rate of video. Higher value means higher quality and larger file size.")
    outputFormLayout.addRow("Video quality:", self.videoQualitySliderWidget)

    self.videoFrameRateSliderWidget = ctk.ctkSliderWidget()
    self.videoFrameRateSliderWidget.singleStep = 0.1
    self.videoFrameRateSliderWidget.minimum = 0.1
    self.videoFrameRateSliderWidget.maximum = 60
    self.videoFrameRateSliderWidget.value = 25
    self.videoFrameRateSliderWidget.decimals = 0
    self.videoFrameRateSliderWidget.setToolTip("Frames per second. Higher values mean faster, shorter videos.")
    outputFormLayout.addRow("Frame rate:", self.videoFrameRateSliderWidget)

    # Capture button
    self.captureButton = qt.QPushButton("Capture")
    self.captureButton.toolTip = "Capture slice sweep to image sequence."
    outputFormLayout.addRow(self.captureButton)
        
    self.statusLabel = qt.QPlainTextEdit()
    self.statusLabel.setTextInteractionFlags(qt.Qt.TextSelectableByMouse)
    self.statusLabel.setCenterOnScroll(True)
    outputFormLayout.addRow(self.statusLabel)

    #
    # Advanced area
    #
    self.advancedCollapsibleButton = ctk.ctkCollapsibleButton()
    self.advancedCollapsibleButton.text = "Advanced"
    self.advancedCollapsibleButton.collapsed = (self.logic.getFfmpegPath() is not None)
    self.layout.addWidget(self.advancedCollapsibleButton)
    advancedFormLayout = qt.QFormLayout(self.advancedCollapsibleButton)

    self.fileNamePatternWidget = qt.QLineEdit()
    self.fileNamePatternWidget.setToolTip("String that defines file name, type, and numbering scheme. Default: image%05d.png.")
    self.fileNamePatternWidget.text = "image_%05d.png"
    advancedFormLayout.addRow("Image file name pattern:", self.fileNamePatternWidget)

    ffmpegPath = self.logic.getFfmpegPath()
    self.ffmpegPathSelector = ctk.ctkPathLineEdit()
    self.ffmpegPathSelector.setCurrentPath(ffmpegPath)
    self.ffmpegPathSelector.nameFilters = ['ffmpeg.exe', 'ffmpeg']
    self.ffmpegPathSelector.setMaximumWidth(300)
    self.ffmpegPathSelector.setToolTip("Set the path to ffmpeg executable. Download from: https://www.ffmpeg.org/")
    self.ffmpegPathSelector.setEnabled(False)
    advancedFormLayout.addRow("ffmpeg executable:", self.ffmpegPathSelector)

    # Add vertical spacer
    self.layout.addStretch(1)
    
    # connections
    self.captureButton.connect('clicked(bool)', self.onCaptureButton)
    self.viewNodeSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onViewNodeSelected)
    self.startSliceOffsetSliderWidget.connect('valueChanged(double)', self.setSliceOffset)
    self.endSliceOffsetSliderWidget.connect('valueChanged(double)', self.setSliceOffset)
    self.videoExportCheckBox.connect('toggled(bool)', self.fileNamePatternWidget, 'setDisabled(bool)')
    self.videoExportCheckBox.connect('toggled(bool)', self.ffmpegPathSelector, 'setEnabled(bool)')
    self.videoExportCheckBox.connect('toggled(bool)', self.videoFileNameWidget, 'setEnabled(bool)')

    self.onViewNodeSelected()
Example #15
0
  def setup(self):
    ScriptedLoadableModuleWidget.setup(self)

    self.logic = ScreenCaptureLogic()
    self.logic.logCallback = self.addLog
    self.viewNodeType = None
    self.animationMode = None

    # Instantiate and connect widgets ...

    #
    # Input area
    #
    inputCollapsibleButton = ctk.ctkCollapsibleButton()
    inputCollapsibleButton.text = "Input"
    self.layout.addWidget(inputCollapsibleButton)
    inputFormLayout = qt.QFormLayout(inputCollapsibleButton)

    # Input view selector
    self.viewNodeSelector = slicer.qMRMLNodeComboBox()
    self.viewNodeSelector.nodeTypes = ["vtkMRMLSliceNode", "vtkMRMLViewNode"]
    self.viewNodeSelector.addEnabled = False
    self.viewNodeSelector.removeEnabled = False
    self.viewNodeSelector.noneEnabled = False
    self.viewNodeSelector.showHidden = False
    self.viewNodeSelector.showChildNodeTypes = False
    self.viewNodeSelector.setMRMLScene( slicer.mrmlScene )
    self.viewNodeSelector.setToolTip( "Contents of this slice or 3D view will be captured." )
    inputFormLayout.addRow("View to capture: ", self.viewNodeSelector)

    # Mode
    self.animationModeWidget = qt.QComboBox()
    self.animationModeWidget.setToolTip("Select the property that will be adjusted")
    inputFormLayout.addRow("Animation mode:", self.animationModeWidget)

    # Slice start offset position
    self.sliceStartOffsetSliderLabel = qt.QLabel("Start sweep offset:")
    self.sliceStartOffsetSliderWidget = ctk.ctkSliderWidget()
    self.sliceStartOffsetSliderWidget.singleStep = 30
    self.sliceStartOffsetSliderWidget.minimum = -100
    self.sliceStartOffsetSliderWidget.maximum = 100
    self.sliceStartOffsetSliderWidget.value = 0
    self.sliceStartOffsetSliderWidget.setToolTip("Start slice sweep offset.")
    inputFormLayout.addRow(self.sliceStartOffsetSliderLabel, self.sliceStartOffsetSliderWidget)

    # Slice end offset position
    self.sliceEndOffsetSliderLabel = qt.QLabel("End sweep offset:")
    self.sliceEndOffsetSliderWidget = ctk.ctkSliderWidget()
    self.sliceEndOffsetSliderWidget.singleStep = 5
    self.sliceEndOffsetSliderWidget.minimum = -100
    self.sliceEndOffsetSliderWidget.maximum = 100
    self.sliceEndOffsetSliderWidget.value = 0
    self.sliceEndOffsetSliderWidget.setToolTip("End slice sweep offset.")
    inputFormLayout.addRow(self.sliceEndOffsetSliderLabel, self.sliceEndOffsetSliderWidget)

    # 3D start rotation
    self.startRotationSliderLabel = qt.QLabel("Start rotation angle:")
    self.startRotationSliderWidget = ctk.ctkSliderWidget()
    self.startRotationSliderWidget.singleStep = 5
    self.startRotationSliderWidget.minimum = 0
    self.startRotationSliderWidget.maximum = 180
    self.startRotationSliderWidget.value = 180
    self.startRotationSliderWidget.setToolTip("Rotation angle for the first image, relative to current orientation.")
    inputFormLayout.addRow(self.startRotationSliderLabel, self.startRotationSliderWidget)

    # 3D end rotation
    self.endRotationSliderLabel = qt.QLabel("End rotation angle:")
    self.endRotationSliderWidget = ctk.ctkSliderWidget()
    self.endRotationSliderWidget.singleStep = 5
    self.endRotationSliderWidget.minimum = 0
    self.endRotationSliderWidget.maximum = 180
    self.endRotationSliderWidget.value = 180
    self.endRotationSliderWidget.setToolTip("Rotation angle for the last image, relative to current orientation.")
    inputFormLayout.addRow(self.endRotationSliderLabel, self.endRotationSliderWidget)

    # Sequence browser node selector
    self.sequenceBrowserNodeSelectorLabel = qt.QLabel("End rotation angle:")
    self.sequenceBrowserNodeSelectorWidget = slicer.qMRMLNodeComboBox()
    self.sequenceBrowserNodeSelectorWidget.nodeTypes = ["vtkMRMLSequenceBrowserNode"]
    self.sequenceBrowserNodeSelectorWidget.addEnabled = False
    self.sequenceBrowserNodeSelectorWidget.removeEnabled = False
    self.sequenceBrowserNodeSelectorWidget.noneEnabled = False
    self.sequenceBrowserNodeSelectorWidget.showHidden = False
    self.sequenceBrowserNodeSelectorWidget.setMRMLScene( slicer.mrmlScene )
    self.sequenceBrowserNodeSelectorWidget.setToolTip( "Items defined by this sequence browser will be replayed." )
    inputFormLayout.addRow(self.sequenceBrowserNodeSelectorLabel, self.sequenceBrowserNodeSelectorWidget)

    # Sequence start index
    self.sequenceStartItemIndexLabel = qt.QLabel("Start index:")
    self.sequenceStartItemIndexWidget = ctk.ctkSliderWidget()
    self.sequenceStartItemIndexWidget.minimum = 0
    self.sequenceStartItemIndexWidget.decimals = 0
    self.sequenceStartItemIndexWidget.setToolTip("First item in the sequence to capture.")
    inputFormLayout.addRow(self.sequenceStartItemIndexLabel, self.sequenceStartItemIndexWidget)

    # Sequence end index
    self.sequenceEndItemIndexLabel = qt.QLabel("End index:")
    self.sequenceEndItemIndexWidget = ctk.ctkSliderWidget()
    self.sequenceEndItemIndexWidget.singleStep = 10
    self.sequenceEndItemIndexWidget.minimum = 0
    self.sequenceEndItemIndexWidget.decimals = 0
    self.sequenceEndItemIndexWidget.setToolTip("Last item in the sequence to capture.")
    inputFormLayout.addRow(self.sequenceEndItemIndexLabel, self.sequenceEndItemIndexWidget)

    #
    # Output area
    #
    outputCollapsibleButton = ctk.ctkCollapsibleButton()
    outputCollapsibleButton.text = "Output"
    self.layout.addWidget(outputCollapsibleButton)
    outputFormLayout = qt.QFormLayout(outputCollapsibleButton)

    # Number of steps value
    self.numberOfStepsSliderWidget = ctk.ctkSliderWidget()
    self.numberOfStepsSliderWidget.singleStep = 10
    self.numberOfStepsSliderWidget.minimum = 2
    self.numberOfStepsSliderWidget.maximum = 150
    self.numberOfStepsSliderWidget.value = 31
    self.numberOfStepsSliderWidget.decimals = 0
    self.numberOfStepsSliderWidget.setToolTip("Number of images extracted between start and stop positions.")
    outputFormLayout.addRow("Number of images:", self.numberOfStepsSliderWidget)

    # Output directory selector
    self.outputDirSelector = ctk.ctkPathLineEdit()
    self.outputDirSelector.filters = ctk.ctkPathLineEdit.Dirs
    self.outputDirSelector.settingKey = 'ScreenCaptureOutputDir'
    outputFormLayout.addRow("Output directory:", self.outputDirSelector)
    if not self.outputDirSelector.currentPath:
      defaultOutputPath = os.path.abspath(os.path.join(slicer.app.defaultScenePath,'SlicerCapture'))
      self.outputDirSelector.setCurrentPath(defaultOutputPath)

    self.videoExportCheckBox = qt.QCheckBox()
    self.videoExportCheckBox.checked = False
    self.videoExportCheckBox.setToolTip("If checked, exported images will be written as a video file."
      " Requires setting of ffmpeg executable path in Advanced section.")
    outputFormLayout.addRow("Video export:", self.videoExportCheckBox)

    self.videoFileNameWidget = qt.QLineEdit()
    self.videoFileNameWidget.setToolTip("String that defines file name, type, and numbering scheme. Default: capture.avi.")
    self.videoFileNameWidget.text = "SlicerCapture.avi"
    self.videoFileNameWidget.setEnabled(False)
    outputFormLayout.addRow("Video file name:", self.videoFileNameWidget)

    self.videoLengthSliderWidget = ctk.ctkSliderWidget()
    self.videoLengthSliderWidget.singleStep = 0.1
    self.videoLengthSliderWidget.minimum = 0.1
    self.videoLengthSliderWidget.maximum = 30
    self.videoLengthSliderWidget.value = 5
    self.videoLengthSliderWidget.suffix = "s"
    self.videoLengthSliderWidget.decimals = 1
    self.videoLengthSliderWidget.setToolTip("Length of the exported video in seconds.")
    self.videoLengthSliderWidget.setEnabled(False)
    outputFormLayout.addRow("Video length:", self.videoLengthSliderWidget)

    #
    # Advanced area
    #
    self.advancedCollapsibleButton = ctk.ctkCollapsibleButton()
    self.advancedCollapsibleButton.text = "Advanced"
    self.advancedCollapsibleButton.collapsed = True
    outputFormLayout.addRow(self.advancedCollapsibleButton)
    advancedFormLayout = qt.QFormLayout(self.advancedCollapsibleButton)

    self.fileNamePatternWidget = qt.QLineEdit()
    self.fileNamePatternWidget.setToolTip(
      "String that defines file name, type, and numbering scheme. Default: image%05d.png.")
    self.fileNamePatternWidget.text = "image_%05d.png"
    advancedFormLayout.addRow("Image file name pattern:", self.fileNamePatternWidget)

    ffmpegPath = self.logic.getFfmpegPath()
    self.ffmpegPathSelector = ctk.ctkPathLineEdit()
    self.ffmpegPathSelector.setCurrentPath(ffmpegPath)
    self.ffmpegPathSelector.nameFilters = ['ffmpeg.exe', 'ffmpeg']
    self.ffmpegPathSelector.setMaximumWidth(300)
    self.ffmpegPathSelector.setToolTip("Set the path to ffmpeg executable. Download from: https://www.ffmpeg.org/")
    advancedFormLayout.addRow("ffmpeg executable:", self.ffmpegPathSelector)

    self.extraVideoOptionsWidget = qt.QComboBox()
    self.extraVideoOptionsWidget.addItem("-c:v mpeg4 -qscale:v 5")
    self.extraVideoOptionsWidget.addItem("-c:v libx264 -preset veryslow -qp 0")
    self.extraVideoOptionsWidget.addItem("-f mp4 -vcodec libx264 -pix_fmt yuv420p")
    self.extraVideoOptionsWidget.setEditable(True)
    self.extraVideoOptionsWidget.setToolTip(
      '<html>\n'
      '  <p>Additional video conversion options passed to ffmpeg.</p>'
      '  <p><b>Examples:</b>'
      '  <ul>'
      '    <li><b>MPEG4: </b>-c:v mpeg4 -qscale:v 5</li>'
      '    <li><b>H264: </b>-c:v libx264 -preset veryslow -qp 0</li>'
      '    <li><b>Quicktime: </b>-f mp4 -vcodec libx264 -pix_fmt yuv420p</li>'
      '  </ul></p>'
      '  <p>See more encoding options at:'
      '  <i>https://trac.ffmpeg.org/wiki/Encode/H.264</i> and'
      '  <i>https://trac.ffmpeg.org/wiki/Encode/MPEG-4</i></p>'
      '</html>')
    advancedFormLayout.addRow("Video extra options:", self.extraVideoOptionsWidget)

    # Capture button
    self.captureButton = qt.QPushButton("Capture")
    self.captureButton.toolTip = "Capture slice sweep to image sequence."
    outputFormLayout.addRow(self.captureButton)

    self.statusLabel = qt.QPlainTextEdit()
    self.statusLabel.setTextInteractionFlags(qt.Qt.TextSelectableByMouse)
    self.statusLabel.setCenterOnScroll(True)
    outputFormLayout.addRow(self.statusLabel)

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

    # connections
    self.captureButton.connect('clicked(bool)', self.onCaptureButton)
    self.viewNodeSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.updateViewOptions)
    self.animationModeWidget.connect("currentIndexChanged(int)", self.updateViewOptions)
    self.sliceStartOffsetSliderWidget.connect('valueChanged(double)', self.setSliceOffset)
    self.sliceEndOffsetSliderWidget.connect('valueChanged(double)', self.setSliceOffset)
    self.sequenceBrowserNodeSelectorWidget.connect("currentNodeChanged(vtkMRMLNode*)", self.updateViewOptions)
    self.sequenceStartItemIndexWidget.connect('valueChanged(double)', self.setSequenceItemIndex)
    self.sequenceEndItemIndexWidget.connect('valueChanged(double)', self.setSequenceItemIndex)
    self.videoExportCheckBox.connect('toggled(bool)', self.fileNamePatternWidget, 'setDisabled(bool)')
    self.videoExportCheckBox.connect('toggled(bool)', self.videoFileNameWidget, 'setEnabled(bool)')
    self.videoExportCheckBox.connect('toggled(bool)', self.videoLengthSliderWidget, 'setEnabled(bool)')

    self.updateViewOptions()
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        # Instantiate and connect widgets ...

        self.dockerGroupBox = ctk.ctkCollapsibleGroupBox()
        self.dockerGroupBox.setTitle('Docker Settings')
        self.layout.addWidget(self.dockerGroupBox)
        dockerForm = qt.QFormLayout(self.dockerGroupBox)
        self.dockerPath = ctk.ctkPathLineEdit()
        # self.dockerPath.setMaximumWidth(300)
        if platform.system() == 'Darwin':
            self.dockerPath.setCurrentPath('/usr/local/bin/docker')
        if platform.system() == 'Linux':
            self.dockerPath.setCurrentPath('/usr/bin/docker')
        if platform.system() == 'Windows':
            self.dockerPath.setCurrentPath(
                "C:/Program Files/Docker/Docker/resources/bin/docker.exe")

        ### use nvidia-docker if it is installed
        nvidiaDockerPath = self.dockerPath.currentPath.replace(
            'bin/docker', 'bin/nvidia-docker')
        if os.path.isfile(nvidiaDockerPath):
            self.dockerPath.setCurrentPath(nvidiaDockerPath)

        self.downloadButton = qt.QPushButton('Download')
        self.downloadButton.connect('clicked(bool)', self.onDownloadButton)
        dockerForm.addRow("Docker Executable Path:", self.dockerPath)
        dockerForm.addRow("Download the docker image:", self.downloadButton)
        self.progressDownload = qt.QProgressBar()
        self.progressDownload.setRange(0, 100)
        self.progressDownload.setValue(0)
        self.progressDownload.hide()

        self.dockerVolumePath = ctk.ctkPathLineEdit()
        defaultVolumePath = os.path.join(expanduser("~"), ".dockerVolume")
        if not os.path.exists(defaultVolumePath):
            os.makedirs(defaultVolumePath)
        self.dockerVolumePath.setCurrentPath(defaultVolumePath)
        dockerForm.addRow("Docker Volume Directory:", self.dockerVolumePath)

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

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

        #
        # input volume selector
        #
        self.inputVolumeSelector = slicer.qMRMLNodeComboBox()
        self.inputVolumeSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"]
        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.inputVolumeSelector.setCurrentNode(None)
        self.inputVolumeSelector.setToolTip("Pick the input to the algorithm.")
        parametersFormLayout.addRow("Input Volume: ", self.inputVolumeSelector)

        #
        # Apply Button
        #
        self.applyButton = qt.QPushButton("Generate Probablity Map")
        self.applyButton.toolTip = "Generate the probablity map."
        self.applyButton.enabled = False
        parametersFormLayout.addRow(self.applyButton)

        #
        # output vessel model selector
        #
        self.outputModelSelector = slicer.qMRMLNodeComboBox()
        self.outputModelSelector.nodeTypes = ["vtkMRMLModelNode"]
        self.outputModelSelector.selectNodeUponCreation = True
        self.outputModelSelector.addEnabled = True
        self.outputModelSelector.removeEnabled = True
        self.outputModelSelector.noneEnabled = True
        self.outputModelSelector.showHidden = False
        self.outputModelSelector.showChildNodeTypes = False
        self.outputModelSelector.setMRMLScene(slicer.mrmlScene)
        self.outputModelSelector.setToolTip(
            "Pick the output to the algorithm.")
        parametersFormLayout.addRow("Output vessel model: ",
                                    self.outputModelSelector)

        #
        # threshold value
        #
        self.imageThresholdSliderWidget = ctk.ctkSliderWidget()
        self.imageThresholdSliderWidget.singleStep = 0.01
        self.imageThresholdSliderWidget.minimum = 0.5
        self.imageThresholdSliderWidget.maximum = 1.0
        self.imageThresholdSliderWidget.value = 0.9
        self.imageThresholdSliderWidget.setToolTip(
            "Set threshold value for computing the output image. Voxels that have intensities lower than this value will set to zero."
        )
        parametersFormLayout.addRow("Image threshold",
                                    self.imageThresholdSliderWidget)

        self.createVesselModelButton = qt.QPushButton("Create Vessel Model")
        self.createVesselModelButton.toolTip = "Generate the vessel model."
        self.createVesselModelButton.enabled = False
        parametersFormLayout.addRow(self.createVesselModelButton)

        # connections
        self.applyButton.connect('clicked(bool)', self.onApplyButton)
        self.createVesselModelButton.connect('clicked(bool)',
                                             self.onCreateModelWithThreshold)
        self.inputVolumeSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                         self.onSelectVolume)
        self.outputModelSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                         self.onSelectModel)

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

        self.logic = DockerVesselSegLogic()
Example #17
0
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        # Instantiate and connect widgets ...
        #
        # Parameters Area
        #
        parametersCollapsibleButton = ctk.ctkCollapsibleButton()
        parametersCollapsibleButton.text = "Parameters"
        self.layout.addWidget(parametersCollapsibleButton)

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

        #
        # Select base mesh
        #
        self.modelSelector = slicer.qMRMLNodeComboBox()
        self.modelSelector.nodeTypes = (("vtkMRMLModelNode"), "")
        self.modelSelector.selectNodeUponCreation = False
        self.modelSelector.addEnabled = False
        self.modelSelector.removeEnabled = False
        self.modelSelector.noneEnabled = True
        self.modelSelector.showHidden = False
        self.modelSelector.setMRMLScene(slicer.mrmlScene)
        parametersFormLayout.addRow("Base mesh: ", self.modelSelector)

        #
        # Select base landmark file
        #
        #self.baseLMFile=ctk.ctkPathLineEdit()
        #self.baseLMFile.setToolTip( "Select file specifying base landmarks" )
        #parametersFormLayout.addRow("Base landmark file: ", self.baseLMFile)
        self.baseLMSelect = slicer.qMRMLNodeComboBox()
        self.baseLMSelect.nodeTypes = (('vtkMRMLMarkupsFiducialNode'), "")
        self.baseLMSelect.selectNodeUponCreation = False
        self.baseLMSelect.addEnabled = False
        self.baseLMSelect.removeEnabled = False
        self.baseLMSelect.noneEnabled = True
        self.baseLMSelect.showHidden = False
        self.baseLMSelect.showChildNodeTypes = False
        self.baseLMSelect.setMRMLScene(slicer.mrmlScene)
        parametersFormLayout.addRow("Base landmarks: ", self.baseLMSelect)

        #
        # Select base semi-landmark file
        #
        #self.semiLMFile=ctk.ctkPathLineEdit()
        #self.semiLMFile.setToolTip( "Select file containing base semi-landmarks " )
        #parametersFormLayout.addRow("Base semi-landmark file: ", self.semiLMFile)
        self.baseSLMSelect = slicer.qMRMLNodeComboBox()
        self.baseSLMSelect.nodeTypes = (('vtkMRMLMarkupsFiducialNode'), "")
        self.baseSLMSelect.selectNodeUponCreation = False
        self.baseSLMSelect.addEnabled = False
        self.baseSLMSelect.removeEnabled = False
        self.baseSLMSelect.noneEnabled = True
        self.baseSLMSelect.showHidden = False
        self.baseSLMSelect.showChildNodeTypes = False
        self.baseSLMSelect.setMRMLScene(slicer.mrmlScene)
        parametersFormLayout.addRow("Base semi-landmarks: ",
                                    self.baseSLMSelect)

        #
        # Select meshes directory
        #
        self.meshDirectory = ctk.ctkPathLineEdit()
        self.meshDirectory.filters = ctk.ctkPathLineEdit.Dirs
        self.meshDirectory.setToolTip("Select directory containing meshes")
        parametersFormLayout.addRow("Mesh directory: ", self.meshDirectory)

        #
        # Select landmarks directory
        #
        self.landmarkDirectory = ctk.ctkPathLineEdit()
        self.landmarkDirectory.filters = ctk.ctkPathLineEdit.Dirs
        self.landmarkDirectory.setToolTip(
            "Select directory containing landmarks")
        parametersFormLayout.addRow("Landmark directory: ",
                                    self.landmarkDirectory)

        #
        # Select output directory
        #
        self.outputDirectory = ctk.ctkPathLineEdit()
        self.outputDirectory.filters = ctk.ctkPathLineEdit.Dirs
        self.outputDirectory.setToolTip("Select directory for output models: ")
        parametersFormLayout.addRow("Output directory: ", self.outputDirectory)

        #
        # Set projection scale
        #
        self.scaleProjection = ctk.ctkSliderWidget()
        self.scaleProjection.singleStep = 1
        self.scaleProjection.minimum = 0
        self.scaleProjection.maximum = 100
        self.scaleProjection.value = 10
        self.scaleProjection.setToolTip(
            "Set scale of maximum point projection")
        parametersFormLayout.addRow("Projection scale: ", self.scaleProjection)

        #
        # Select output extension
        #
        self.JSONType = qt.QRadioButton()
        self.JSONType.setChecked(True)
        parametersFormLayout.addRow("MRK.JSON output: ", self.JSONType)
        self.FCSVType = qt.QRadioButton()
        parametersFormLayout.addRow("FCSV output: ", self.FCSVType)

        #
        # Apply Button
        #
        self.applyButton = qt.QPushButton("Apply")
        self.applyButton.toolTip = "Generate ProjectSemiLMs."
        self.applyButton.enabled = False
        parametersFormLayout.addRow(self.applyButton)

        # connections
        self.modelSelector.connect('currentNodeChanged(vtkMRMLNode*)',
                                   self.onSelect)
        self.baseLMSelect.connect('currentNodeChanged(vtkMRMLNode*)',
                                  self.onSelect)
        self.baseSLMSelect.connect('currentNodeChanged(vtkMRMLNode*)',
                                   self.onSelect)
        self.meshDirectory.connect('validInputChanged(bool)', self.onSelect)
        self.landmarkDirectory.connect('validInputChanged(bool)',
                                       self.onSelect)
        self.outputDirectory.connect('validInputChanged(bool)', self.onSelect)
        self.applyButton.connect('clicked(bool)', self.onApplyButton)

        # Add vertical spacer
        self.layout.addStretch(1)
  def _addCustomizationSection(self):
    customizationCollapsibleButton = ctk.ctkCollapsibleButton()
    customizationCollapsibleButton.text = 'Extraction Customization'
    customizationCollapsibleButton.collapsed = True
    self.layout.addWidget(customizationCollapsibleButton)

    customizationFormLayout = qt.QFormLayout(customizationCollapsibleButton)

    #
    # Radiobuttons to select customization Type
    #

    self.manualCustomizationRadioButton = qt.QRadioButton()
    self.manualCustomizationRadioButton.text = 'Manual Customization'
    self.manualCustomizationRadioButton.checked = True
    customizationFormLayout.layout().addWidget(self.manualCustomizationRadioButton)

    self.parameterFileCustomizationRadioButton = qt.QRadioButton()
    self.parameterFileCustomizationRadioButton.text = 'Parameter File Customization'
    self.parameterFileCustomizationRadioButton.checked = False
    customizationFormLayout.layout().addWidget(self.parameterFileCustomizationRadioButton)

    #
    # Manual Customization
    #
    self.manualCustomizationGroupBox = qt.QGroupBox('Manual Customization')
    self.manualCustomizationGroupBox.visible = True
    # self.manualCustomizationGroupBox.checkable = True
    customizationFormLayout.addWidget(self.manualCustomizationGroupBox)

    manualCustomizationFormLayout = qt.QFormLayout(self.manualCustomizationGroupBox)

    # Feature Class section
    featureClassCollapsibleButton = ctk.ctkCollapsibleButton()
    featureClassCollapsibleButton.text = 'Feature Classes'
    featureClassCollapsibleButton.collapsed = False
    manualCustomizationFormLayout.addWidget(featureClassCollapsibleButton)

    featureClassLayout = qt.QFormLayout(featureClassCollapsibleButton)

    self.featuresLayout = qt.QHBoxLayout()
    featureClassLayout.addRow('Features:', self.featuresLayout)

    self.featuresButtonGroup = qt.QButtonGroup(self.featuresLayout)
    self.featuresButtonGroup.exclusive = False

    # Get the feature classes dynamically
    self.features = list(getFeatureClasses().keys())
    # Create a checkbox for each feature
    featureButtons = {}
    for feature in self.features:
      featureButtons[feature] = qt.QCheckBox(feature)
      # TODO: decide which features to enable by default
      featureButtons[feature].checked = False
      if feature == 'firstorder':
        featureButtons[feature].checked = True
      self.featuresButtonGroup.addButton(featureButtons[feature])
      self.featuresLayout.layout().addWidget(featureButtons[feature])
      # set the ID to be the index of this feature in the list
      self.featuresButtonGroup.setId(featureButtons[feature], self.features.index(feature))

    # Add buttons to select all or none
    self.buttonsLayout = qt.QHBoxLayout()
    featureClassLayout.addRow('Toggle Features:', self.buttonsLayout)

    self.calculateAllFeaturesButton = qt.QPushButton('All Features')
    self.calculateAllFeaturesButton.toolTip = 'Calculate all feature classes.'
    self.calculateAllFeaturesButton.enabled = True
    self.buttonsLayout.addWidget(self.calculateAllFeaturesButton)
    self.calculateNoFeaturesButton = qt.QPushButton('No Features')
    self.calculateNoFeaturesButton.toolTip = 'Calculate no feature classes.'
    self.calculateNoFeaturesButton.enabled = True
    self.buttonsLayout.addWidget(self.calculateNoFeaturesButton)

    # Resampling and Filtering
    filteringCollapsibleButton = ctk.ctkCollapsibleButton()
    filteringCollapsibleButton.text = 'Resampling and Filtering'
    filteringCollapsibleButton.collapsed = False
    manualCustomizationFormLayout.addRow(filteringCollapsibleButton)
    # Layout within the dummy collapsible button
    filteringFormLayout = qt.QFormLayout(filteringCollapsibleButton)

    # Resampling
    self.resampledVoxelSize = qt.QLineEdit()
    self.resampledVoxelSize.toolTip = 'Three floating-point numbers separated by comma defining the resampled pixel ' \
                                      'size (mm).'
    filteringFormLayout.addRow('Resampled voxel size', self.resampledVoxelSize)

    # LoG kernel sizes. default to 5 (?)
    self.logKernelSizes = qt.QLineEdit()
    self.logKernelSizes.toolTip = 'Laplacian of Gaussian filter kernel sizes (mm), separated by comma. ' \
                                  'If empty, no LoG filtering will be applied.'
    filteringFormLayout.addRow('LoG kernel sizes', self.logKernelSizes)

    # Wavelet
    self.waveletCheckBox = qt.QCheckBox()
    self.waveletCheckBox.checked = 0
    self.waveletCheckBox.toolTip = 'If checked, PyRadiomics will calculate features on the image after applying ' \
                                   'wavelet transformation'
    filteringFormLayout.addRow('Wavelet-based features', self.waveletCheckBox)

    #
    # Feature calculation settings
    #
    settingsCollapsibleButton = ctk.ctkCollapsibleButton()
    settingsCollapsibleButton.text = 'Settings'
    settingsCollapsibleButton.collapsed = False
    manualCustomizationFormLayout.addWidget(settingsCollapsibleButton)

    # Layout within the dummy collapsible button
    settingsFormLayout = qt.QFormLayout(settingsCollapsibleButton)

    # bin width, defaults to 25
    self.binWidthSliderWidget = ctk.ctkSliderWidget()
    self.binWidthSliderWidget.singleStep = 1
    self.binWidthSliderWidget.decimals = 2
    self.binWidthSliderWidget.minimum = 0.01
    self.binWidthSliderWidget.maximum = 100
    self.binWidthSliderWidget.value = 25
    self.binWidthSliderWidget.toolTip = 'Set the bin width'
    settingsFormLayout.addRow('Bin Width', self.binWidthSliderWidget)

    # symmetricalGLCM flag, defaults to false
    self.symmetricalGLCMCheckBox = qt.QCheckBox()
    self.symmetricalGLCMCheckBox.checked = 1
    self.symmetricalGLCMCheckBox.toolTip = 'Use a symmetrical GLCM matrix'
    settingsFormLayout.addRow('Enforce Symmetrical GLCM', self.symmetricalGLCMCheckBox)

    #
    # Parameter File Customization
    #

    self.parameterCustomizationGroupBox = qt.QGroupBox('Parameter File Customization')
    self.parameterCustomizationGroupBox.visible = False
    # self.parameterCustomizationGroupBox.checkable = True
    customizationFormLayout.addWidget(self.parameterCustomizationGroupBox)

    parameterCustomizationFormLayout = qt.QFormLayout(self.parameterCustomizationGroupBox)

    # Path edit to select parameter file
    self.parameterFilePathLineEdit = ctk.ctkPathLineEdit()
    parameterCustomizationFormLayout.addRow("Parameter File", self.parameterFilePathLineEdit)
Example #19
0
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        # Instantiate and connect widgets ...

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

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

        #
        # Select landmark file to import
        #
        self.inputDirectory = ctk.ctkPathLineEdit()
        self.inputDirectory.filters = ctk.ctkPathLineEdit.Dirs
        self.inputDirectory.setToolTip(
            "Select directory containing curves to resample")
        parametersFormLayout.addRow("Input Directory:", self.inputDirectory)

        #
        # output directory selector
        #
        self.outputDirectory = ctk.ctkPathLineEdit()
        self.outputDirectory.filters = ctk.ctkPathLineEdit.Dirs
        self.outputDirectory.currentPath = slicer.app.temporaryPath
        parametersFormLayout.addRow("Output Directory:", self.outputDirectory)

        #
        # Get Resample number
        #
        self.ResampleRateWidget = ctk.ctkDoubleSpinBox()
        self.ResampleRateWidget.value = 50
        self.ResampleRateWidget.minimum = 3
        self.ResampleRateWidget.maximum = 5000
        self.ResampleRateWidget.singleStep = 1
        self.ResampleRateWidget.setDecimals(0)
        self.ResampleRateWidget.setToolTip(
            "Select the number of points for resampling: ")
        parametersFormLayout.addRow("Output sample number: ",
                                    self.ResampleRateWidget)

        #
        # Get open or closed curve option
        #
        curveTypeSelector = qt.QHBoxLayout()
        self.curveTypeOpen = qt.QRadioButton("open")
        self.curveTypeOpen.setToolTip(
            "Select option for no interpolation between first and last points")
        self.curveTypeOpen.setChecked(True)
        self.curveTypeClosed = qt.QRadioButton("closed")
        self.curveTypeClosed.setToolTip(
            "Select option to interpolate between first and last points")
        curveTypeSelector.addWidget(self.curveTypeOpen)
        curveTypeSelector.addWidget(self.curveTypeClosed)
        curveTypeSelector.addStretch()
        parametersFormLayout.addRow("Curve Type: ", curveTypeSelector)

        #
        # check box to trigger taking screen shots for later use in tutorials
        #
        self.enableScreenshotsFlagCheckBox = qt.QCheckBox()
        self.enableScreenshotsFlagCheckBox.checked = 0
        self.enableScreenshotsFlagCheckBox.setToolTip(
            "If checked, take screen shots for tutorials. Use Save Data to write them to disk."
        )
        parametersFormLayout.addRow("Enable Screenshots",
                                    self.enableScreenshotsFlagCheckBox)

        #
        # Apply Button
        #
        self.applyButton = qt.QPushButton("Apply")
        self.applyButton.toolTip = "Run the conversion."
        self.applyButton.enabled = False
        parametersFormLayout.addRow(self.applyButton)

        # connections
        self.applyButton.connect('clicked(bool)', self.onApplyButton)
        self.inputDirectory.connect('validInputChanged(bool)',
                                    self.onSelectInput)

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

        # Refresh Apply button state
        self.onSelectInput()
Example #20
0
    def setup(self):
        self.logic = HerniaAnnotationModuleLogic()

        ScriptedLoadableModuleWidget.setup(self)

        self.detectionOn = False

        self.updateTimer = qt.QTimer()
        self.updateTimer.setInterval(100)
        self.updateTimer.setSingleShot(True)
        self.updateTimer.connect('timeout()', self.onUpdateTimer)

        # Instantiate and connect widgets ...

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

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

        #
        # input volume selector
        #
        self.inputSelector = slicer.qMRMLNodeComboBox()
        self.inputSelector.nodeTypes = ["vtkMRMLStreamingVolumeNode"]
        self.inputSelector.selectNodeUponCreation = True
        self.inputSelector.addEnabled = False
        self.inputSelector.removeEnabled = False
        self.inputSelector.noneEnabled = False
        self.inputSelector.showHidden = False
        self.inputSelector.showChildNodeTypes = False
        self.inputSelector.setMRMLScene(slicer.mrmlScene)
        self.inputSelector.setToolTip("Pick the input to the algorithm.")
        parametersFormLayout.addRow("Input Volume: ", self.inputSelector)

        self.toolOneSelector = slicer.qMRMLNodeComboBox()
        self.toolOneSelector.nodeTypes = ["vtkMRMLLinearTransformNode"]
        self.toolOneSelector.selectNodeUponCreation = True
        self.toolOneSelector.addEnabled = False
        self.toolOneSelector.removeEnabled = False
        self.toolOneSelector.noneEnabled = False
        self.toolOneSelector.showHidden = False
        self.toolOneSelector.showChildNodeTypes = False
        self.toolOneSelector.setMRMLScene(slicer.mrmlScene)
        self.toolOneSelector.setToolTip("Pick the input to the algorithm.")
        parametersFormLayout.addRow("Input Tool One: ", self.toolOneSelector)

        self.toolTwoSelector = slicer.qMRMLNodeComboBox()
        self.toolTwoSelector.nodeTypes = ["vtkMRMLLinearTransformNode"]
        self.toolTwoSelector.selectNodeUponCreation = True
        self.toolTwoSelector.addEnabled = False
        self.toolTwoSelector.removeEnabled = False
        self.toolTwoSelector.noneEnabled = False
        self.toolTwoSelector.showHidden = False
        self.toolTwoSelector.showChildNodeTypes = False
        self.toolTwoSelector.setMRMLScene(slicer.mrmlScene)
        self.toolTwoSelector.setToolTip("Pick the input to the algorithm.")
        parametersFormLayout.addRow("Input Tool Two: ", self.toolTwoSelector)

        self.modelPathEdit = ctk.ctkPathLineEdit()
        parametersFormLayout.addRow("Keras model: ", self.modelPathEdit)

        #
        # threshold value
        #
        self.imageThresholdSliderWidget = ctk.ctkSliderWidget()
        self.imageThresholdSliderWidget.singleStep = 0.05
        self.imageThresholdSliderWidget.minimum = 0
        self.imageThresholdSliderWidget.maximum = 1.0
        self.imageThresholdSliderWidget.value = 0.5
        self.imageThresholdSliderWidget.setToolTip(
            "Set threshold value for class probability.")
        parametersFormLayout.addRow("Prediction threshold",
                                    self.imageThresholdSliderWidget)

        #
        # Apply Button
        #
        self.applyButton = qt.QPushButton("Start detection")
        self.applyButton.toolTip = "Run the algorithm."
        self.applyButton.enabled = True
        parametersFormLayout.addRow(self.applyButton)

        self.toolLabel = qt.QLabel("0")
        toolFont = self.toolLabel.font
        toolFont.setPointSize(32)
        self.toolLabel.setFont(toolFont)
        parametersFormLayout.addRow("Tool: ", self.toolLabel)

        self.classLabel = qt.QLabel("0")
        classFont = self.classLabel.font
        classFont.setPointSize(32)
        self.classLabel.setFont(classFont)
        parametersFormLayout.addRow("Tissue: ", self.classLabel)

        # connections
        self.applyButton.connect('clicked(bool)', self.onApplyButton)

        # Add vertical spacer
        self.layout.addStretch(1)
Example #21
0
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        # Instantiate and connect widgets ...

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

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

        #
        # Select landmark file to import
        #
        self.inputFileSelector = ctk.ctkPathLineEdit()
        self.inputFileSelector.filters = ctk.ctkPathLineEdit().Files
        self.inputFileSelector.setToolTip("Select landmark file for import")
        parametersFormLayout.addRow(
            "Select file containing landmark names and coordinates to load:",
            self.inputFileSelector)

        #
        # output directory selector
        #
        self.outputDirectory = ctk.ctkDirectoryButton()
        self.outputDirectory.directory = slicer.mrmlScene.GetCacheManager(
        ).GetRemoteCacheDirectory()
        parametersFormLayout.addRow("Output Directory:", self.outputDirectory)

        #
        # Get header length
        #
        self.headerLengthWidget = ctk.ctkDoubleSpinBox()
        self.headerLengthWidget.value = 2
        self.headerLengthWidget.minimum = 0
        self.headerLengthWidget.singleStep = 1
        self.headerLengthWidget.setToolTip(
            "Input the number of lines in header")
        parametersFormLayout.addRow("Header length:", self.headerLengthWidget)

        #
        # check box to trigger taking screen shots for later use in tutorials
        #
        self.loadLandmarkNode = qt.QCheckBox()
        self.loadLandmarkNode.checked = 0
        self.loadLandmarkNode.setToolTip(
            "After conversion, load landmarks into the scene.")
        parametersFormLayout.addRow("Load landmarks into scene",
                                    self.loadLandmarkNode)

        #
        # Apply Button
        #
        self.applyButton = qt.QPushButton("Apply")
        self.applyButton.toolTip = "Run the algorithm."
        self.applyButton.enabled = False
        parametersFormLayout.addRow(self.applyButton)

        # connections
        self.applyButton.connect('clicked(bool)', self.onApplyButton)
        self.inputFileSelector.connect('validInputChanged(bool)',
                                       self.onSelect)

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

        # Refresh Apply button state
        self.onSelect()
Example #22
0
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        # Set up tabs to split workflow
        tabsWidget = qt.QTabWidget()
        alignSingleTab = qt.QWidget()
        alignSingleTabLayout = qt.QFormLayout(alignSingleTab)
        alignMultiTab = qt.QWidget()
        alignMultiTabLayout = qt.QFormLayout(alignMultiTab)

        tabsWidget.addTab(alignSingleTab, "Single Alignment")
        tabsWidget.addTab(alignMultiTab, "Batch processing")
        self.layout.addWidget(tabsWidget)

        # Layout within the tab
        alignSingleWidget = ctk.ctkCollapsibleButton()
        alignSingleWidgetLayout = qt.QFormLayout(alignSingleWidget)
        alignSingleWidget.text = "Align and subsample a source and reference mesh "
        alignSingleTabLayout.addRow(alignSingleWidget)

        #
        # Select source mesh
        #
        self.sourceModelSelector = ctk.ctkPathLineEdit()
        self.sourceModelSelector.filters = ctk.ctkPathLineEdit().Files
        self.sourceModelSelector.nameFilters = ["*.ply"]
        alignSingleWidgetLayout.addRow("Source mesh: ",
                                       self.sourceModelSelector)

        #
        # Select source landmarks
        #
        self.sourceFiducialSelector = ctk.ctkPathLineEdit()
        self.sourceFiducialSelector.filters = ctk.ctkPathLineEdit().Files
        self.sourceFiducialSelector.nameFilters = ["*.fcsv"]
        alignSingleWidgetLayout.addRow("Source landmarks: ",
                                       self.sourceFiducialSelector)

        # Select target mesh
        #
        self.targetModelSelector = ctk.ctkPathLineEdit()
        self.targetModelSelector.filters = ctk.ctkPathLineEdit().Files
        self.targetModelSelector.nameFilters = ["*.ply"]
        alignSingleWidgetLayout.addRow("Reference mesh: ",
                                       self.targetModelSelector)

        self.skipScalingCheckBox = qt.QCheckBox()
        self.skipScalingCheckBox.checked = 0
        self.skipScalingCheckBox.setToolTip(
            "If checked, PointCloudRegistration will skip scaling during the alignment (Not recommended)."
        )
        alignSingleWidgetLayout.addRow("Skip scaling",
                                       self.skipScalingCheckBox)

        [
            self.pointDensity, self.normalSearchRadius, self.FPFHSearchRadius,
            self.distanceThreshold, self.maxRANSAC, self.maxRANSACValidation,
            self.ICPDistanceThreshold
        ] = self.addAdvancedMenu(alignSingleWidgetLayout)

        # Advanced tab connections
        self.pointDensity.connect('valueChanged(double)',
                                  self.onChangeAdvanced)
        self.normalSearchRadius.connect('valueChanged(double)',
                                        self.onChangeAdvanced)
        self.FPFHSearchRadius.connect('valueChanged(double)',
                                      self.onChangeAdvanced)
        self.distanceThreshold.connect('valueChanged(double)',
                                       self.onChangeAdvanced)
        self.maxRANSAC.connect('valueChanged(double)', self.onChangeAdvanced)
        self.maxRANSACValidation.connect('valueChanged(double)',
                                         self.onChangeAdvanced)
        self.ICPDistanceThreshold.connect('valueChanged(double)',
                                          self.onChangeAdvanced)

        #
        # Subsample Button
        #
        self.subsampleButton = qt.QPushButton("Run subsampling")
        self.subsampleButton.toolTip = "Run subsampling of the source and reference meshes"
        self.subsampleButton.enabled = False
        alignSingleWidgetLayout.addRow(self.subsampleButton)

        #
        # Subsample Information
        #
        self.subsampleInfo = qt.QPlainTextEdit()
        self.subsampleInfo.setPlaceholderText("Subsampling information")
        self.subsampleInfo.setReadOnly(True)
        alignSingleWidgetLayout.addRow(self.subsampleInfo)

        #
        # Align Button
        #
        self.alignButton = qt.QPushButton("Run rigid alignment")
        self.alignButton.toolTip = "Run rigid alignment of the source and reference meshes"
        self.alignButton.enabled = False
        alignSingleWidgetLayout.addRow(self.alignButton)

        #
        # Plot Aligned Mesh Button
        #
        self.displayMeshButton = qt.QPushButton("Display alignment")
        self.displayMeshButton.toolTip = "Display rigid alignment of the source and references meshes"
        self.displayMeshButton.enabled = False
        alignSingleWidgetLayout.addRow(self.displayMeshButton)

        # connections
        self.sourceModelSelector.connect('validInputChanged(bool)',
                                         self.onSelect)
        self.sourceFiducialSelector.connect('validInputChanged(bool)',
                                            self.onSelect)
        self.targetModelSelector.connect('validInputChanged(bool)',
                                         self.onSelect)
        self.subsampleButton.connect('clicked(bool)', self.onSubsampleButton)
        self.alignButton.connect('clicked(bool)', self.onAlignButton)
        self.displayMeshButton.connect('clicked(bool)',
                                       self.onDisplayMeshButton)

        # Layout within the multiprocessing tab
        alignMultiWidget = ctk.ctkCollapsibleButton()
        alignMultiWidgetLayout = qt.QFormLayout(alignMultiWidget)
        alignMultiWidget.text = "Alings landmarks from multiple specimens to a reference 3d model (mesh)"
        alignMultiTabLayout.addRow(alignMultiWidget)

        #
        # Select source mesh
        #
        self.sourceModelMultiSelector = ctk.ctkPathLineEdit()
        self.sourceModelMultiSelector.filters = ctk.ctkPathLineEdit.Dirs
        self.sourceModelMultiSelector.toolTip = "Select the directory containing the source meshes"
        alignMultiWidgetLayout.addRow("Source mesh directory: ",
                                      self.sourceModelMultiSelector)

        #
        # Select source landmark file
        #
        self.sourceFiducialMultiSelector = ctk.ctkPathLineEdit()
        self.sourceFiducialMultiSelector.filters = ctk.ctkPathLineEdit.Dirs
        self.sourceFiducialMultiSelector.toolTip = "Select the directory containing the source landmarks"
        alignMultiWidgetLayout.addRow("Source landmark directory: ",
                                      self.sourceFiducialMultiSelector)

        # Select target mesh directory
        #
        self.targetModelMultiSelector = ctk.ctkPathLineEdit()
        self.targetModelMultiSelector.filters = ctk.ctkPathLineEdit().Files
        self.targetModelMultiSelector.nameFilters = ["*.ply"]
        alignMultiWidgetLayout.addRow("Reference mesh: ",
                                      self.targetModelMultiSelector)

        # Select output landmark directory
        #
        self.landmarkOutputSelector = ctk.ctkPathLineEdit()
        self.landmarkOutputSelector.filters = ctk.ctkPathLineEdit.Dirs
        self.landmarkOutputSelector.toolTip = "Select the output directory where the landmarks will be saved"
        alignMultiWidgetLayout.addRow("Output landmark directory: ",
                                      self.landmarkOutputSelector)

        self.skipScalingMultiCheckBox = qt.QCheckBox()
        self.skipScalingMultiCheckBox.checked = 0
        self.skipScalingMultiCheckBox.setToolTip(
            "If checked, PointCloudRegistration will skip scaling during the alignment."
        )
        alignMultiWidgetLayout.addRow("Skip scaling",
                                      self.skipScalingMultiCheckBox)

        [
            self.pointDensityMulti, self.normalSearchRadiusMulti,
            self.FPFHSearchRadiusMulti, self.distanceThresholdMulti,
            self.maxRANSACMulti, self.maxRANSACValidationMulti,
            self.ICPDistanceThresholdMulti
        ] = self.addAdvancedMenu(alignMultiWidgetLayout)

        #
        # Run landmarking Button
        #
        self.applyLandmarkMultiButton = qt.QPushButton(
            "Run PointCloud Registration")
        self.applyLandmarkMultiButton.toolTip = "Align the source meshes and landmarks with a reference mesh"
        self.applyLandmarkMultiButton.enabled = False
        alignMultiWidgetLayout.addRow(self.applyLandmarkMultiButton)

        # connections
        self.sourceModelMultiSelector.connect('validInputChanged(bool)',
                                              self.onSelectMultiProcess)
        self.sourceFiducialMultiSelector.connect('validInputChanged(bool)',
                                                 self.onSelectMultiProcess)
        self.targetModelMultiSelector.connect('validInputChanged(bool)',
                                              self.onSelectMultiProcess)
        self.landmarkOutputSelector.connect('validInputChanged(bool)',
                                            self.onSelectMultiProcess)
        self.skipScalingMultiCheckBox.connect('validInputChanged(bool)',
                                              self.onSelectMultiProcess)
        self.applyLandmarkMultiButton.connect('clicked(bool)',
                                              self.onApplyLandmarkMulti)

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

        # Advanced tab connections
        self.pointDensityMulti.connect('valueChanged(double)',
                                       self.updateParameterDictionary)
        self.normalSearchRadiusMulti.connect('valueChanged(double)',
                                             self.updateParameterDictionary)
        self.FPFHSearchRadiusMulti.connect('valueChanged(double)',
                                           self.updateParameterDictionary)
        self.distanceThresholdMulti.connect('valueChanged(double)',
                                            self.updateParameterDictionary)
        self.maxRANSACMulti.connect('valueChanged(double)',
                                    self.updateParameterDictionary)
        self.maxRANSACValidationMulti.connect('valueChanged(double)',
                                              self.updateParameterDictionary)
        self.ICPDistanceThresholdMulti.connect('valueChanged(double)',
                                               self.updateParameterDictionary)

        # initialize the parameter dictionary from single run parameters
        self.parameterDictionary = {
            "pointDensity": self.pointDensity.value,
            "normalSearchRadius": self.normalSearchRadius.value,
            "FPFHSearchRadius": self.FPFHSearchRadius.value,
            "distanceThreshold": self.distanceThreshold.value,
            "maxRANSAC": int(self.maxRANSAC.value),
            "maxRANSACValidation": int(self.maxRANSACValidation.value),
            "ICPDistanceThreshold": self.ICPDistanceThreshold.value
        }
        # initialize the parameter dictionary from multi run parameters
        self.parameterDictionaryMulti = {
            "pointDensity": self.pointDensityMulti.value,
            "normalSearchRadius": self.normalSearchRadiusMulti.value,
            "FPFHSearchRadius": self.FPFHSearchRadiusMulti.value,
            "distanceThreshold": self.distanceThresholdMulti.value,
            "maxRANSAC": int(self.maxRANSACMulti.value),
            "maxRANSACValidation": int(self.maxRANSACValidationMulti.value),
            "ICPDistanceThreshold": self.ICPDistanceThresholdMulti.value
        }
Example #23
0
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        self.logic = MyModuleLogic()

        # ------ 1. CREATE LAYOUT AND BUTTONS ------

        # Layout setup: 3D Only
        self.layoutManager = slicer.app.layoutManager()
        self.layoutManager.setLayout(
            slicer.vtkMRMLLayoutNode.SlicerLayoutOneUp3DView)

        #
        # LOAD DATA
        #

        # Create layout
        collapsibleButtonLoad = ctk.ctkCollapsibleButton()
        collapsibleButtonLoad.text = "LOAD DATA"  # title for layout
        self.layout.addWidget(collapsibleButtonLoad)
        formLayout_load = qt.QFormLayout(collapsibleButtonLoad)

        # Segment 1 Selector
        self.segment1_pathSelector = ctk.ctkPathLineEdit()
        self.segment1_pathSelector.enabled = True
        self.segment1_pathSelector.setMaximumWidth(400)
        self.segment1_pathSelector.currentPath = slicer.modules.mymodule.path.replace(
            "MyModule.py", "") + 'Data/Liver1.stl'
        formLayout_load.addRow("Segment 1: ", self.segment1_pathSelector)

        # Segment 1 Selector
        self.segment2_pathSelector = ctk.ctkPathLineEdit()
        self.segment2_pathSelector.enabled = True
        self.segment2_pathSelector.setMaximumWidth(400)
        self.segment2_pathSelector.currentPath = slicer.modules.mymodule.path.replace(
            "MyModule.py", "") + 'Data/Liver1beforeMM.stl'
        formLayout_load.addRow("Segment 2: ", self.segment2_pathSelector)

        # Button to load segments
        self.loadSegmentsButton = qt.QPushButton(
            "LOAD MODELS AS SEGMENTS")  # text in button
        self.loadSegmentsButton.toolTip = "Load segments as segments"  # hint text for button (appears when cursor is above the button for more than one second)
        self.loadSegmentsButton.enabled = True  # if True it can be clicked
        formLayout_load.addRow(
            self.loadSegmentsButton)  # include button in layout

        #
        # ALIGNMENT
        #

        # Create Layout
        collapsibleButtonAlignment = ctk.ctkCollapsibleButton()
        collapsibleButtonAlignment.text = "ALIGNMENT"
        self.layout.addWidget(collapsibleButtonAlignment)
        formLayout_alignment = qt.QFormLayout(collapsibleButtonAlignment)

        # Button for masks alignment
        self.alignSegmentsButton = qt.QPushButton(
            "ALIGN MODELS")  # text in button
        self.alignSegmentsButton.toolTip = "Align segments"  # hint text for button (appears when cursor is above the button for more than one second)
        self.alignSegmentsButton.enabled = True
        formLayout_alignment.addRow(self.alignSegmentsButton)

        #       COMPARISON BETWEEN MASKS         #
        # SORENSEN-DICE COEFFICIENT & HOUSDORFF DISTANCE BUTTONS
        #

        # Create layout
        collapsibleButtonComparison = ctk.ctkCollapsibleButton()
        collapsibleButtonComparison.text = "COMPARISON"  # title for layout
        self.layout.addWidget(collapsibleButtonComparison)
        formLayout_comparison = qt.QFormLayout(collapsibleButtonComparison)

        # Button to obtain the Sorensen-Dice Coefficient
        self.diceCoeffButton = qt.QPushButton(
            "SORENSEN-DICE COEFFICIENT")  # text in button
        self.diceCoeffButton.toolTip = "Sorensen-Dice Coefficient"  # hint text for button (appears when the cursor is above the button for more than one second)
        self.diceCoeffButton.enabled = True  # if true it can be clicked
        formLayout_comparison.addRow(
            self.diceCoeffButton)  # include button in layout

        #Button to obtain the Hausdorff Distance
        self.hausDistButton = qt.QPushButton(
            "HAUSDORFF DISTANCE")  # text in button
        self.hausDistButton.toolTip = qt.QPushButton(
            "Hausdorff Distance"
        )  # hint text for button (appears when the cursor is above the button for more than a second)
        self.hausDistButton.enabled = True  # if true it can be clicked
        formLayout_comparison.addRow(
            self.hausDistButton)  # include button in layout

        #
        # VISUALIZATION
        #

        # Create layout
        collapsibleButtonVisualization = ctk.ctkCollapsibleButton()
        collapsibleButtonVisualization.text = "VISUALIZATION"  # title for layout
        self.layout.addWidget(collapsibleButtonVisualization)
        formLayout_visualization = qt.QFormLayout(
            collapsibleButtonVisualization)

        #
        # Segment visibility layout
        #

        # Create collapsible button inside layout
        segmentVisibility_GroupBox = ctk.ctkCollapsibleGroupBox()
        segmentVisibility_GroupBox.setTitle(
            "MODEL VISIBILITY")  # title for collapsible button
        segmentVisibility_GroupBox.collapsed = False  # if True it appears collapsed
        formLayout_visualization.addRow(
            segmentVisibility_GroupBox)  # add collapsible button to layout

        # Create layout inside collapsible button
        segmentVisibility_GroupBox_Layout = qt.QFormLayout(
            segmentVisibility_GroupBox)

        # Create horizontal section
        segmentVisibilityLayout_1 = qt.QHBoxLayout()
        segmentVisibility_GroupBox_Layout.addRow(
            segmentVisibilityLayout_1)  # insert section in current layout

        # Show or Hide Segment 1 in 3D scene
        self.segment1_checkBox = qt.QCheckBox('Segment 1')  # text in checkbox
        self.segment1_checkBox.checked = True  # if True it is initially checked
        self.segment1_checkBox.enabled = True  # if True it can be checked
        segmentVisibilityLayout_1.addWidget(
            self.segment1_checkBox)  # add checkbox to layout

        # Show or Hide Segment 2 in 3D scene
        self.segment2_checkBox = qt.QCheckBox('Segment 2')  # text in checkbox
        self.segment2_checkBox.checked = True  # if True it is initially checked
        self.segment2_checkBox.checked = True  # if True it can be checked
        segmentVisibilityLayout_1.addWidget(
            self.segment2_checkBox)  # add checkbox to layout

        #
        # Segment transparency layout
        #

        # Create collapsible button inside layout
        segmentOpacity_GroupBox = ctk.ctkCollapsibleGroupBox()
        segmentOpacity_GroupBox.setTitle(
            "MODEL OPACITY")  # title for collapsible button
        segmentOpacity_GroupBox.collapsed = False  # if True it appears collapsed
        formLayout_visualization.addRow(
            segmentOpacity_GroupBox)  # add collapsible button to layout

        # Create layout inside collapsible button
        segmentOpacity_GroupBox_Layout = qt.QFormLayout(
            segmentOpacity_GroupBox)

        # Create an opacity Value Slider - Segment 1
        self.opacityValueSliderWidget_1 = ctk.ctkSliderWidget()
        self.opacityValueSliderWidget_1.singleStep = 5  # step for range of values to be selected
        self.opacityValueSliderWidget_1.minimum = 0  # minimum value
        self.opacityValueSliderWidget_1.maximum = 100  # maximum value
        self.opacityValueSliderWidget_1.value = 100  # initial value
        segmentOpacity_GroupBox_Layout.addRow(
            "[%]: ", self.opacityValueSliderWidget_1)  # add slider to layout

        # Create an opacity Value Slider - Segment 2
        self.opacityValueSliderWidget_2 = ctk.ctkSliderWidget()
        self.opacityValueSliderWidget_2.singleStep = 5  # step for range of values to be selected
        self.opacityValueSliderWidget_2.minimum = 0  # minimum value
        self.opacityValueSliderWidget_2.maximum = 100  # maximum value
        self.opacityValueSliderWidget_2.value = 100  # initial value
        segmentOpacity_GroupBox_Layout.addRow(
            "[%]: ", self.opacityValueSliderWidget_2)  # add slider to layout

        #
        # COLOR MAP
        #
        collapsibleButtonColorMap = ctk.ctkCollapsibleButton()
        collapsibleButtonColorMap.text = "COLOR MAP"
        self.layout.addWidget(collapsibleButtonColorMap)
        formLayout_colorMap = qt.QFormLayout(collapsibleButtonColorMap)

        self.showColorMapButton = qt.QPushButton(
            "SHOW COLOR MAP")  # text in button
        self.showColorMapButton.toolTip = "Align segments"  # hint text for button (appears when cursor is above the button for more than one second)
        self.showColorMapButton.enabled = True
        formLayout_colorMap.addRow(self.showColorMapButton)

        # Displayed Range group box
        self.displayedRange_GroupBox = ctk.ctkCollapsibleGroupBox()
        self.displayedRange_GroupBox.setTitle("Displayed Range")
        self.displayedRange_GroupBox.collapsed = False
        self.displayedRange_GroupBox.enabled = False
        formLayout_colorMap.addRow(self.displayedRange_GroupBox)
        displayedRange_GroupBox_Layout = qt.QFormLayout(
            self.displayedRange_GroupBox)
        displayedRange_H_Layout = qt.QHBoxLayout()
        displayedRange_GroupBox_Layout.addRow(displayedRange_H_Layout)

        ## Minimum value - displayed range
        self.minDisplayedRange_SpinBox = qt.QDoubleSpinBox()
        self.minDisplayedRange_SpinBox.setMaximum(40.0)
        self.minDisplayedRange_SpinBox.setMinimum(-40.0)
        self.minDisplayedRange_SpinBox.setSingleStep(0.1)
        self.minDisplayedRange_SpinBox.enabled = True
        self.minDisplayedRange_SpinBox.value = 0.0
        displayedRange_H_Layout.addWidget(self.minDisplayedRange_SpinBox)

        ## Displayed range Slider
        self.displayedRange_SliderWidget = ctk.ctkDoubleRangeSlider()
        self.displayedRange_SliderWidget.setValues(0.0, 10.0)
        self.displayedRange_SliderWidget.orientation = 1
        self.displayedRange_SliderWidget.singleStep = 0.1
        self.displayedRange_SliderWidget.minimum = -40.0
        self.displayedRange_SliderWidget.maximum = 40.0
        displayedRange_H_Layout.addWidget(self.displayedRange_SliderWidget)

        ## Maximum value - displayed range
        self.maxDisplayedRange_SpinBox = qt.QDoubleSpinBox()
        self.maxDisplayedRange_SpinBox.setMaximum(40.0)
        self.maxDisplayedRange_SpinBox.setMinimum(-40.0)
        self.maxDisplayedRange_SpinBox.setSingleStep(0.1)
        self.maxDisplayedRange_SpinBox.enabled = True
        self.maxDisplayedRange_SpinBox.value = 10.0
        displayedRange_H_Layout.addWidget(self.maxDisplayedRange_SpinBox)

        # Scalar Bar Visibility Checkbox
        self.ScalarBar_visibility_checkBox = qt.QCheckBox('Scalar Bar Visible')
        self.ScalarBar_visibility_checkBox.checked = True
        displayedRange_GroupBox_Layout.addRow(
            self.ScalarBar_visibility_checkBox)

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

        # ------ 2. CONNECT BUTTONS WITH FUNCTIONS ------

        # Connect each button with a function
        self.loadSegmentsButton.connect(
            'clicked(bool)', self.onloadSegmentsButton
        )  # when the button is pressed we call the function onLoadSegment1Button
        self.segment1_checkBox.connect('stateChanged(int)',
                                       self.onupdateSegment1Visibility)
        self.segment2_checkBox.connect('stateChanged(int)',
                                       self.onupdateSegment2Visibility)
        self.opacityValueSliderWidget_1.connect("valueChanged(double)",
                                                self.onupdateSegment1Opacity)
        self.opacityValueSliderWidget_2.connect("valueChanged(double)",
                                                self.onupdateSegment2Opacity)
        self.alignSegmentsButton.connect('clicked(bool)',
                                         self.onAlignSegmentsButton)
        self.diceCoeffButton.connect('clicked(bool)', self.onDiceCoeffButton)
        self.hausDistButton.connect('clicked(bool)',
                                    self.onHausdorffDistButton)
        self.showColorMapButton.connect('clicked(bool)',
                                        self.onShowColorMapButton)
        self.displayedRange_SliderWidget.connect(
            "valuesChanged(double,double)", self.onDisplayedRangeSliderChanged)
        self.minDisplayedRange_SpinBox.connect(
            "valueChanged(double)", self.onDisplayedRangeSpinBoxChanged)
        self.maxDisplayedRange_SpinBox.connect(
            "valueChanged(double)", self.onDisplayedRangeSpinBoxChanged)
        self.ScalarBar_visibility_checkBox.connect(
            'stateChanged(int)', self.onScalarBarVisibilityChecked)
Example #24
0
  def setup(self):
    ScriptedLoadableModuleWidget.setup(self)

    # Instantiate and connect widgets ...


    #
    # File area
    #
    filesCollapsibleButton = ctk.ctkCollapsibleButton()
    filesCollapsibleButton.text = "Files"
    filesCollapsibleButton.collapsed = False
    self.layout.addWidget(filesCollapsibleButton)
    # Layout within the files collapsible button
    filesFormLayout = qt.QFormLayout(filesCollapsibleButton)

    self.fileModel = qt.QStandardItemModel()
    self.fileTable = qt.QTableView()
    self.fileTable.horizontalHeader().stretchLastSection = True
    self.fileTable.horizontalHeader().visible = False
    self.fileTable.setModel(self.fileModel)
    filesFormLayout.addRow(self.fileTable)

    buttonLayout = qt.QHBoxLayout()
    self.addByBrowsingButton = qt.QPushButton("Browse for files")
    self.clearFilesButton = qt.QPushButton("Clear files")
    buttonLayout.addWidget(self.addByBrowsingButton)
    buttonLayout.addWidget(self.clearFilesButton)
    filesFormLayout.addRow(buttonLayout)

    #
    # output area
    #
    outputCollapsibleButton = ctk.ctkCollapsibleButton()
    outputCollapsibleButton.text = "Output"
    outputCollapsibleButton.collapsed = False
    self.layout.addWidget(outputCollapsibleButton)
    outputFormLayout = qt.QFormLayout(outputCollapsibleButton)

    #
    # output volume selector
    #
    #self.outputSelector = slicer.qMRMLSubjectHierarchyComboBox()
    self.outputSelector = slicer.qMRMLNodeComboBox()

    self.outputSelector.nodeTypes = ["vtkMRMLScalarVolumeNode",]
    #self.outputSelector.setNodeTypes(["vtkMRMLScalarVolumeNode",]) ; TODO: make nodeTypes property for SH box


    """
    TODO: which are supported and needed for SubjectHierarchy combo box.
    TODO: can we delete/rename/create as with SH
    self.outputSelector.defaultText = "Create new volume." ; # TODO any way to reset value?
    """
    self.outputSelector.showChildNodeTypes = False
    self.outputSelector.showHidden = False
    self.outputSelector.showChildNodeTypes = False
    self.outputSelector.selectNodeUponCreation = False
    self.outputSelector.noneEnabled = True
    self.outputSelector.removeEnabled = True
    self.outputSelector.renameEnabled = True
    self.outputSelector.addEnabled = True
    self.outputSelector.setMRMLScene( slicer.mrmlScene )
    self.outputSelector.setToolTip( "Pick the output volume to populate or None to autogenerate." )
    outputFormLayout.addRow("Output Volume: ", self.outputSelector)

    self.spacing = ctk.ctkCoordinatesWidget()
    self.spacing.coordinates = "1,1,1"
    self.spacing.toolTip = "Set the colunm, row, slice spacing in mm"
    outputFormLayout.addRow("Spacing: ", self.spacing)


    self.loadButton = qt.QPushButton("Load files")
    outputFormLayout.addRow(self.loadButton)

    #
    # Add by name area
    #
    addByNameCollapsibleButton = ctk.ctkCollapsibleButton()
    addByNameCollapsibleButton.text = "Add files by name"
    addByNameCollapsibleButton.collapsed = True
    addByNameFormLayout = qt.QFormLayout(addByNameCollapsibleButton)
    # Don't enable Add by name for now - let's see if it's actually needed
    # self.layout.addWidget(addByNameCollapsibleButton)

    forExample = """
    directoryPath = '/Volumes/SSD2T/data/SlicerMorph/Sample_for_steve/1326_Rec'
    pathFormat = '%s/1326__rec%04d.png'
    start, end =  (50, 621)
    """

    self.archetypePathEdit = ctk.ctkPathLineEdit()
    addByNameFormLayout.addRow("Archetype file", self.archetypePathEdit)

    self.archetypeFormat = qt.QLineEdit()
    addByNameFormLayout.addRow("Name format", self.archetypeFormat)

    self.indexRange = ctk.ctkRangeWidget()
    self.indexRange.decimals = 0
    self.indexRange.maximum = 0
    addByNameFormLayout.addRow("Index range", self.indexRange)

    self.generateNamesButton = qt.QPushButton("Apply")
    self.generateNamesButton.toolTip = "Run the algorithm."
    self.generateNamesButton.enabled = False
    addByNameFormLayout.addRow(self.generateNamesButton)

    # connections
    self.addByBrowsingButton.connect('clicked()', self.addByBrowsing)
    self.clearFilesButton.connect('clicked()', self.fileTable.model().clear)
    self.archetypePathEdit.connect('currentPathChanged(QString)', self.validateInput)
    self.archetypePathEdit.connect('currentPathChanged(QString)', self.updateGUIFromArchetype)
    self.archetypeFormat.connect('textChanged(QString)', self.validateInput)
    self.generateNamesButton.connect('clicked()', self.onGenerateNames)
    # self.outputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.validateInput) # TODO - this is missing
    self.loadButton.connect('clicked()', self.onLoadButton)

    # refill last selection
    self.archetypePathEdit.currentPath = slicer.util.settingsValue("ImageStacks/lastArchetypePath", "")


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

    # Refresh Apply button state
    self.validateInput()
Example #25
0
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        # Instantiate and connect widgets ...

        # Set up tabs to split workflow
        tabsWidget = qt.QTabWidget()
        curvesTab = qt.QWidget()
        curvesTabLayout = qt.QFormLayout(curvesTab)
        fiducialsTab = qt.QWidget()
        fiducialsTabLayout = qt.QFormLayout(fiducialsTab)
        batchTab = qt.QWidget()
        batchTabLayout = qt.QFormLayout(batchTab)

        tabsWidget.addTab(curvesTab, "Merge Curves")
        tabsWidget.addTab(fiducialsTab, "Merge Landmark Sets")
        tabsWidget.addTab(batchTab, "Batch Merge Landmark Sets")
        self.layout.addWidget(tabsWidget)
        ################## Curves Tab
        #
        # Parameters Area
        #
        parametersCurveCollapsibleButton = ctk.ctkCollapsibleButton()
        parametersCurveCollapsibleButton.text = "Curve Viewer"
        curvesTabLayout.addRow(parametersCurveCollapsibleButton)

        # Layout within the dummy collapsible button
        parametersCurveFormLayout = qt.QFormLayout(
            parametersCurveCollapsibleButton)

        #
        # check box to trigger taking screen shots for later use in tutorials
        #
        self.continuousCurvesCheckBox = qt.QCheckBox()
        self.continuousCurvesCheckBox.checked = 0
        self.continuousCurvesCheckBox.setToolTip(
            "If checked, redundant points will be removed on merging.")
        parametersCurveFormLayout.addRow("Contiuous curves",
                                         self.continuousCurvesCheckBox)

        #
        # markups view
        #
        self.markupsView = slicer.qMRMLSubjectHierarchyTreeView()
        self.markupsView.setMRMLScene(slicer.mrmlScene)
        self.markupsView.setMultiSelection(True)
        self.markupsView.setAlternatingRowColors(True)
        self.markupsView.setDragDropMode(qt.QAbstractItemView().DragDrop)
        self.markupsView.setColumnHidden(
            self.markupsView.model().transformColumn, True)
        self.markupsView.sortFilterProxyModel().setNodeTypes(
            ["vtkMRMLMarkupsCurveNode"])
        parametersCurveFormLayout.addRow(self.markupsView)

        #
        # Merge Button
        #
        self.mergeButton = qt.QPushButton("Merge highlighted nodes")
        self.mergeButton.toolTip = "Generate a single merged markup file from the selected nodes"
        self.mergeButton.enabled = False
        parametersCurveFormLayout.addRow(self.mergeButton)

        # connections
        self.mergeButton.connect('clicked(bool)', self.onMergeButton)
        self.markupsView.connect('currentItemChanged(vtkIdType)',
                                 self.updateMergeButton)

        ################ Landmark Set Tab
        #
        # Parameters Area
        #
        parametersLMCollapsibleButton = ctk.ctkCollapsibleButton()
        parametersLMCollapsibleButton.text = "Landmark Viewer"
        fiducialsTabLayout.addRow(parametersLMCollapsibleButton)

        # Layout within the dummy collapsible button
        parametersLMFormLayout = qt.QGridLayout(parametersLMCollapsibleButton)

        #
        # markups view
        #
        self.markupsFiducialView = slicer.qMRMLSubjectHierarchyTreeView()
        self.markupsFiducialView.setMRMLScene(slicer.mrmlScene)
        self.markupsFiducialView.setMultiSelection(True)
        self.markupsFiducialView.setAlternatingRowColors(True)
        self.markupsFiducialView.setDragDropMode(
            qt.QAbstractItemView().DragDrop)
        self.markupsFiducialView.setColumnHidden(
            self.markupsView.model().transformColumn, True)
        self.markupsFiducialView.sortFilterProxyModel().setNodeTypes(
            ["vtkMRMLMarkupsFiducialNode"])
        parametersLMFormLayout.addWidget(self.markupsFiducialView, 0, 0, 1, 3)

        #
        # Set landmark type menu
        #
        boxLabel = qt.QLabel("Select landmark type description to apply: ")
        self.LandmarkTypeSelection = qt.QComboBox()
        self.LandmarkTypeSelection.addItems(
            ["Select", "Fixed", "Semi", "No description"])
        parametersLMFormLayout.addWidget(boxLabel, 1, 0)
        parametersLMFormLayout.addWidget(self.LandmarkTypeSelection, 1, 1)

        #
        # Apply Landmark Type Button
        #
        self.ApplyLMButton = qt.QPushButton("Apply to highlighted nodes")
        self.ApplyLMButton.toolTip = "Apply the selected landmark type to points in the the selected nodes"
        self.ApplyLMButton.enabled = False
        parametersLMFormLayout.addWidget(self.ApplyLMButton, 1, 2)

        #
        # Merge Button
        #
        self.mergeLMButton = qt.QPushButton("Merge highlighted nodes")
        self.mergeLMButton.toolTip = "Generate a single merged markup file from the selected nodes"
        self.mergeLMButton.enabled = False
        parametersLMFormLayout.addWidget(self.mergeLMButton, 2, 0, 1, 3)

        # connections
        self.mergeLMButton.connect('clicked(bool)', self.onMergeLMButton)
        self.ApplyLMButton.connect('clicked(bool)', self.onApplyLMButton)
        self.markupsFiducialView.connect('currentItemChanged(vtkIdType)',
                                         self.updateMergeLMButton)
        self.LandmarkTypeSelection.connect('currentIndexChanged(int)',
                                           self.updateApplyLMButton)

        ################ Batch Run LM Merge Tab
        #
        # Fixed LM Area
        #
        fixedBatchCollapsibleButton = ctk.ctkCollapsibleButton()
        fixedBatchCollapsibleButton.text = "Fixed LM File Selection"
        batchTabLayout.addRow(fixedBatchCollapsibleButton)

        # Layout within the dummy collapsible button
        fixedBatchLayout = qt.QFormLayout(fixedBatchCollapsibleButton)

        #
        # Browse Fixed LM Button
        #
        self.browseFixedLMButton = qt.QPushButton("Select files...")
        self.browseFixedLMButton.toolTip = "Select one fixed landmark file for each subject"
        self.browseFixedLMButton.enabled = True
        fixedBatchLayout.addRow(self.browseFixedLMButton)

        #
        # File viewer box
        #
        self.fixedFileTable = qt.QTextEdit()
        fixedBatchLayout.addRow(self.fixedFileTable)

        #
        # Semi LM Area
        #
        semiBatchCollapsibleButton = ctk.ctkCollapsibleButton()
        semiBatchCollapsibleButton.text = "Semi LM File Selection"
        batchTabLayout.addRow(semiBatchCollapsibleButton)

        # Layout within the dummy collapsible button
        semiBatchLayout = qt.QFormLayout(semiBatchCollapsibleButton)

        #
        # Browse Fixed LM Button
        #
        self.browseSemiLMButton = qt.QPushButton("Select files...")
        self.browseSemiLMButton.toolTip = "Select one semi-landmark file for each subject, in the same order as the fixed landmarks"
        self.browseSemiLMButton.enabled = True
        semiBatchLayout.addRow(self.browseSemiLMButton)

        #
        # File viewer box
        #
        self.semiFileTable = qt.QTextEdit()
        semiBatchLayout.addRow(self.semiFileTable)

        #
        # Merge LM Area
        #
        batchMergeCollapsibleButton = ctk.ctkCollapsibleButton()
        batchMergeCollapsibleButton.text = "Run merge"
        batchTabLayout.addRow(batchMergeCollapsibleButton)

        # Layout within the dummy collapsible button
        batchMergeLayout = qt.QFormLayout(batchMergeCollapsibleButton)

        #
        # Select output landmark directory
        #
        self.outputDirectorySelector = ctk.ctkPathLineEdit()
        self.outputDirectorySelector.filters = ctk.ctkPathLineEdit.Dirs
        self.outputDirectorySelector.toolTip = "Select the output directory where the merged landmark nodes will be saved"
        batchMergeLayout.addRow("Select output landmark directory: ",
                                self.outputDirectorySelector)

        #
        # Batch Merge Button
        #
        self.batchMergeButton = qt.QPushButton(
            "Merge fixed and semi-landmark nodes")
        self.batchMergeButton.toolTip = "Generate a single merged markup file from the selected nodes"
        self.batchMergeButton.enabled = False
        batchMergeLayout.addRow(self.batchMergeButton)

        #
        # Clear Button
        #
        self.clearButton = qt.QPushButton("Clear landmark file selections")
        self.clearButton.toolTip = "Clear the landmark files selected in the viewer boxes"
        self.clearButton.enabled = False
        batchMergeLayout.addRow(self.clearButton)

        # connections
        self.browseFixedLMButton.connect('clicked(bool)',
                                         self.addFixedByBrowsing)
        self.browseSemiLMButton.connect('clicked(bool)',
                                        self.addSemiByBrowsing)
        self.outputDirectorySelector.connect('validInputChanged(bool)',
                                             self.onSelectDirectory)
        self.batchMergeButton.connect('clicked(bool)', self.onBatchMergeButton)
        self.clearButton.connect('clicked(bool)', self.onClearButton)

        # Add vertical spacer
        self.layout.addStretch(1)
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        # Launch PureData

        pureDataCollapsibleButton = ctk.ctkCollapsibleButton()
        pureDataCollapsibleButton.text = "PureData server"
        self.layout.addWidget(pureDataCollapsibleButton)
        pureDataFormLayout = qt.QFormLayout(pureDataCollapsibleButton)

        self.pureDataConfigFilePathSelector = ctk.ctkPathLineEdit()
        self.pureDataConfigFilePathSelector.settingKey = "OpenSoundControl/PureDataConfigurationFilePath"
        self.pureDataConfigFilePathSelector.setSizePolicy(
            qt.QSizePolicy.MinimumExpanding, qt.QSizePolicy.Preferred)
        self.pureDataConfigFilePathSelector.setToolTip(
            "Set PureData configuration file that will be loaded when the server is launched."
        )
        pureDataFormLayout.addRow("PureData configuration:",
                                  self.pureDataConfigFilePathSelector)

        self.buttonStartServer = qt.QPushButton("Start server")
        self.buttonStartServer.toolTip = "Start PureData server that will receive OSC messages"
        self.buttonStartServer.connect('clicked()', self.startServer)

        self.buttonStopServer = qt.QPushButton("Stop server")
        self.buttonStopServer.toolTip = "Stop PureData server"
        self.buttonStopServer.connect('clicked()', self.stopServer)

        hbox = qt.QHBoxLayout()
        hbox.addWidget(self.buttonStartServer)
        hbox.addWidget(self.buttonStopServer)
        pureDataFormLayout.addRow(hbox)

        # Connection

        connectionCollapsibleButton = ctk.ctkCollapsibleButton()
        connectionCollapsibleButton.text = "Connection"
        self.layout.addWidget(connectionCollapsibleButton)
        connectionFormLayout = qt.QFormLayout(connectionCollapsibleButton)

        self.hostnameLineEdit = qt.QLineEdit("localhost")
        connectionFormLayout.addRow("Host name: ", self.hostnameLineEdit)

        self.portLineEdit = qt.QLineEdit("7400")
        self.portLineEdit.setValidator(
            qt.QIntValidator(0, 65535, self.portLineEdit))
        connectionFormLayout.addRow("Port: ", self.portLineEdit)

        self.buttonConnect = qt.QPushButton("Connect")
        self.buttonConnect.toolTip = "Connect to OSC module"
        connectionFormLayout.addWidget(self.buttonConnect)
        self.buttonConnect.connect('clicked()', self.connect)

        # Send message

        messageCollapsibleButton = ctk.ctkCollapsibleButton()
        messageCollapsibleButton.text = "Messaging"
        self.layout.addWidget(messageCollapsibleButton)
        messageFormLayout = qt.QFormLayout(messageCollapsibleButton)

        self.addressLineEdit = qt.QLineEdit()
        self.addressLineEdit.setText("/SoundNav/1")
        messageFormLayout.addRow("Address:", self.addressLineEdit)

        self.valueLineEdit = qt.QLineEdit()
        self.valueLineEdit.setText("")
        messageFormLayout.addRow("Value:", self.valueLineEdit)

        self.buttonSend = qt.QPushButton("Send")
        self.buttonSend.toolTip = "Send OSC message"
        messageFormLayout.addWidget(self.buttonSend)
        self.buttonSend.connect('clicked(bool)', self.sendMessage)

        #
        # Advanced area
        #
        self.advancedCollapsibleButton = ctk.ctkCollapsibleButton()
        self.advancedCollapsibleButton.text = "Advanced"
        self.advancedCollapsibleButton.collapsed = True
        self.layout.addWidget(self.advancedCollapsibleButton)
        advancedFormLayout = qt.QFormLayout(self.advancedCollapsibleButton)

        self.logDetailsCheckBox = qt.QCheckBox(" ")
        self.logDetailsCheckBox.checked = False
        self.logDetailsCheckBox.setToolTip(
            "Add details about all sent messages to the application log. It may slow down the execution."
        )
        advancedFormLayout.addRow("Log messages:", self.logDetailsCheckBox)
        self.logDetailsCheckBox.connect("toggled(bool)",
                                        self.logic.setLoggingEnabled)

        pureDataExecutablePath = self.logic.getPureDataExecutablePath()
        self.pureDataExecutablePathSelector = ctk.ctkPathLineEdit()
        self.pureDataExecutablePathSelector.filters = ctk.ctkPathLineEdit.Executable + ctk.ctkPathLineEdit.Files
        from sys import platform
        self.pureDataExecutablePathSelector.nameFilters = [
            "PureData (pd.exe)" if platform == "win32" else "PureData (pd*)"
        ]
        self.pureDataExecutablePathSelector.setCurrentPath(
            pureDataExecutablePath)
        self.pureDataExecutablePathSelector.setSizePolicy(
            qt.QSizePolicy.MinimumExpanding, qt.QSizePolicy.Preferred)
        self.pureDataExecutablePathSelector.setToolTip(
            "Set PureData executable (pd) path.")
        advancedFormLayout.addRow("PureData executable:",
                                  self.pureDataExecutablePathSelector)
        self.pureDataExecutablePathSelector.connect(
            'currentPathChanged(QString)',
            self.logic.setPureDataExecutablePath)

        self.showPureDataGUI = qt.QCheckBox(" ")
        self.showPureDataGUI.checked = False
        self.showPureDataGUI.setToolTip(
            "Start PureData server with graphical user interface visible. Useful for development and troubleshooting."
        )
        advancedFormLayout.addRow("Start PureData with GUI:",
                                  self.showPureDataGUI)

        # Add vertical spacer
        self.layout.addStretch(1)
Example #27
0
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        # Instantiate and connect widgets ...

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

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

        self.inputDirectory = ctk.ctkPathLineEdit()
        self.inputDirectory.filters = ctk.ctkPathLineEdit.Dirs
        self.inputDirectory.setToolTip("Select directory containing volumes")
        parametersFormLayout.addRow("Input directory: ", self.inputDirectory)

        # Select output directory
        self.outputDirectory = ctk.ctkPathLineEdit()
        self.outputDirectory.filters = ctk.ctkPathLineEdit.Dirs
        self.outputDirectory.setToolTip("Select directory for output models: ")
        parametersFormLayout.addRow("Output directory: ", self.outputDirectory)

        #
        # Select the extension type
        #
        self.extensionOptionGZ = qt.QRadioButton(".nii.gz")
        self.extensionOptionGZ.setChecked(True)
        parametersFormLayout.addRow("Select extension type: ",
                                    self.extensionOptionGZ)

        #
        # set threshold value
        #
        self.threshold = ctk.ctkDoubleSpinBox()
        self.threshold.singleStep = 1
        self.threshold.minimum = 0
        self.threshold.maximum = 100000
        self.threshold.setDecimals(0)
        self.threshold.value = 500
        self.threshold.setToolTip(
            "Select threshold for segmentation of volume")
        parametersFormLayout.addRow("Threshold for segmentation:",
                                    self.threshold)
        #
        # Apply Button
        #
        self.applyButton = qt.QPushButton("Apply")
        self.applyButton.toolTip = "Generate VolumeToMeshs."
        self.applyButton.enabled = False
        parametersFormLayout.addRow(self.applyButton)

        #
        # check box to trigger taking screen shots for later use in tutorials
        #
        self.enableScreenshotsFlagCheckBox = qt.QCheckBox()
        self.enableScreenshotsFlagCheckBox.checked = 0
        self.enableScreenshotsFlagCheckBox.setToolTip(
            "If checked, take screen shots for tutorials. Use Save Data to write them to disk."
        )
        parametersFormLayout.addRow("Enable Screenshots",
                                    self.enableScreenshotsFlagCheckBox)

        # connections
        self.inputDirectory.connect('validInputChanged(bool)',
                                    self.onSelectInput)
        self.outputDirectory.connect('validInputChanged(bool)',
                                     self.onSelectOutput)
        self.applyButton.connect('clicked(bool)', self.onApplyButton)

        # Add vertical spacer
        self.layout.addStretch(1)
Example #28
0
  def setup(self):
    ScriptedLoadableModuleWidget.setup(self)

    self.logic = ElastixLogic()
    self.logic.logCallback = self.addLog
    self.registrationInProgress = False

    # Instantiate and connect widgets ...

    # Parameter sets
    defaultinputParametersCollapsibleButton = ctk.ctkCollapsibleButton()
    defaultinputParametersCollapsibleButton.text = "Parameter set"
    defaultinputParametersCollapsibleButton.collapsed = True
    self.layout.addWidget(defaultinputParametersCollapsibleButton)
    defaultParametersLayout = qt.QFormLayout(defaultinputParametersCollapsibleButton)

    self.parameterNodeSelector = slicer.qMRMLNodeComboBox()
    self.parameterNodeSelector.nodeTypes = ["vtkMRMLScriptedModuleNode"]
    self.parameterNodeSelector.addAttribute( "vtkMRMLScriptedModuleNode", "ModuleName", "Elastix" )
    self.parameterNodeSelector.selectNodeUponCreation = True
    self.parameterNodeSelector.addEnabled = True
    self.parameterNodeSelector.renameEnabled = True
    self.parameterNodeSelector.removeEnabled = True
    self.parameterNodeSelector.noneEnabled = False
    self.parameterNodeSelector.showHidden = True
    self.parameterNodeSelector.showChildNodeTypes = False
    self.parameterNodeSelector.baseName = "General Registration (Elastix)"
    self.parameterNodeSelector.setMRMLScene( slicer.mrmlScene )
    self.parameterNodeSelector.setToolTip( "Pick parameter set" )
    defaultParametersLayout.addRow("Parameter set: ", self.parameterNodeSelector)

    #
    # Inputs
    #
    inputParametersCollapsibleButton = ctk.ctkCollapsibleButton()
    inputParametersCollapsibleButton.text = "Inputs"
    self.layout.addWidget(inputParametersCollapsibleButton)

    # Layout within the dummy collapsible button
    inputParametersFormLayout = qt.QFormLayout(inputParametersCollapsibleButton)

    #
    # fixed volume selector
    #
    self.fixedVolumeSelector = slicer.qMRMLNodeComboBox()
    self.fixedVolumeSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"]
    self.fixedVolumeSelector.selectNodeUponCreation = True
    self.fixedVolumeSelector.addEnabled = False
    self.fixedVolumeSelector.removeEnabled = False
    self.fixedVolumeSelector.noneEnabled = False
    self.fixedVolumeSelector.showHidden = False
    self.fixedVolumeSelector.showChildNodeTypes = False
    self.fixedVolumeSelector.setMRMLScene( slicer.mrmlScene )
    self.fixedVolumeSelector.setToolTip( "The moving volume will be transformed into this image space." )
    inputParametersFormLayout.addRow("Fixed volume: ", self.fixedVolumeSelector)

    #
    # moving volume selector
    #
    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.movingVolumeSelector.setToolTip( "This volume will be transformed into the fixed image space" )
    inputParametersFormLayout.addRow("Moving volume: ", self.movingVolumeSelector)

    self.registrationPresetSelector = qt.QComboBox()
    for preset in self.logic.getRegistrationPresets():
      self.registrationPresetSelector.addItem("{0} ({1})".format(preset[RegistrationPresets_Modality], preset[RegistrationPresets_Content]))
    inputParametersFormLayout.addRow("Preset: ", self.registrationPresetSelector)

    #
    # Outputs
    #
    maskingParametersCollapsibleButton = ctk.ctkCollapsibleButton()
    maskingParametersCollapsibleButton.text = "Masking"
    maskingParametersCollapsibleButton.collapsed = True
    self.layout.addWidget(maskingParametersCollapsibleButton)

    # Layout within the dummy collapsible button
    maskingParametersFormLayout = qt.QFormLayout(maskingParametersCollapsibleButton)

    #
    # fixed volume mask selector
    #
    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.fixedVolumeMaskSelector.setToolTip("Areas of the fixed volume where mask label is 0 will be ignored in the registration.")
    maskingParametersFormLayout.addRow("Fixed volume mask: ", self.fixedVolumeMaskSelector)

    #
    # 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("Areas of the moving volume where mask label is 0 will be ignored in the registration")
    maskingParametersFormLayout.addRow("Moving volume mask: ", self.movingVolumeMaskSelector)

    #
    # Outputs
    #
    outputParametersCollapsibleButton = ctk.ctkCollapsibleButton()
    outputParametersCollapsibleButton.text = "Outputs"
    self.layout.addWidget(outputParametersCollapsibleButton)

    # Layout within the dummy collapsible button
    outputParametersFormLayout = qt.QFormLayout(outputParametersCollapsibleButton)

    #
    # 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.outputVolumeSelector.setToolTip( "(optional) The moving image warped to the fixed image space. NOTE: You must set at least one output object (transform and/or output volume)" )
    outputParametersFormLayout.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.outputTransformSelector.setToolTip( "(optional) Computed displacement field that transform nodes from moving volume space to fixed volume space. NOTE: You must set at least one output object (transform and/or output volume)." )
    outputParametersFormLayout.addRow("Output transform: ", self.outputTransformSelector)

    #
    # Advanced area
    #
    self.advancedCollapsibleButton = ctk.ctkCollapsibleButton()
    self.advancedCollapsibleButton.text = "Advanced"
    self.advancedCollapsibleButton.collapsed = True
    self.layout.addWidget(self.advancedCollapsibleButton)
    advancedFormLayout = qt.QFormLayout(self.advancedCollapsibleButton)

    self.showDetailedLogDuringExecutionCheckBox = qt.QCheckBox(" ")
    self.showDetailedLogDuringExecutionCheckBox.checked = False
    self.showDetailedLogDuringExecutionCheckBox.setToolTip("Show detailed log during registration.")
    advancedFormLayout.addRow("Show detailed log during registration:", self.showDetailedLogDuringExecutionCheckBox)

    self.keepTemporaryFilesCheckBox = qt.QCheckBox(" ")
    self.keepTemporaryFilesCheckBox.checked = False
    self.keepTemporaryFilesCheckBox.setToolTip("Keep temporary files (inputs, computed outputs, logs) after the registration is completed.")

    self.showTemporaryFilesFolderButton = qt.QPushButton("Show temp folder")
    self.showTemporaryFilesFolderButton.toolTip = "Open the folder where temporary files are stored."
    self.showTemporaryFilesFolderButton.setSizePolicy(qt.QSizePolicy.MinimumExpanding, qt.QSizePolicy.Preferred)

    hbox = qt.QHBoxLayout()
    hbox.addWidget(self.keepTemporaryFilesCheckBox)
    hbox.addWidget(self.showTemporaryFilesFolderButton)
    advancedFormLayout.addRow("Keep temporary files:", hbox)

    self.showRegistrationParametersDatabaseFolderButton = qt.QPushButton("Show database folder")
    self.showRegistrationParametersDatabaseFolderButton.toolTip = "Open the folder where temporary files are stored."
    self.showRegistrationParametersDatabaseFolderButton.setSizePolicy(qt.QSizePolicy.MinimumExpanding, qt.QSizePolicy.Preferred)
    advancedFormLayout.addRow("Registration presets:", self.showRegistrationParametersDatabaseFolderButton)

    customElastixBinDir = self.logic.getCustomElastixBinDir()
    self.customElastixBinDirSelector = ctk.ctkPathLineEdit()
    self.customElastixBinDirSelector.filters = ctk.ctkPathLineEdit.Dirs
    self.customElastixBinDirSelector.setCurrentPath(customElastixBinDir)
    self.customElastixBinDirSelector.setSizePolicy(qt.QSizePolicy.MinimumExpanding, qt.QSizePolicy.Preferred)
    self.customElastixBinDirSelector.setToolTip("Set bin directory of an Elastix installation (where elastix executable is located). "
      "If value is empty then default elastix (bundled with SlicerElastix extension) will be used.")
    advancedFormLayout.addRow("Custom Elastix toolbox location:", self.customElastixBinDirSelector)

    #
    # Apply Button
    #
    self.applyButton = qt.QPushButton("Apply")
    self.applyButton.toolTip = "Run the algorithm."
    self.applyButton.enabled = False
    self.layout.addWidget(self.applyButton)

    self.statusLabel = qt.QPlainTextEdit()
    self.statusLabel.setTextInteractionFlags(qt.Qt.TextSelectableByMouse)
    self.statusLabel.setCenterOnScroll(True)
    self.layout.addWidget(self.statusLabel)

    # connections
    self.applyButton.connect('clicked(bool)', self.onApplyButton)
    self.showTemporaryFilesFolderButton.connect('clicked(bool)', self.onShowTemporaryFilesFolder)
    self.showRegistrationParametersDatabaseFolderButton.connect('clicked(bool)', self.onShowRegistrationParametersDatabaseFolder)
    self.fixedVolumeSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect)
    self.movingVolumeSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect)
    self.outputVolumeSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect)
    self.outputTransformSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect)
    # Immediately update deleteTemporaryFiles in the logic to make it possible to decide to
    # keep the temporary file while the registration is running
    self.keepTemporaryFilesCheckBox.connect("toggled(bool)", self.onKeepTemporaryFilesToggled)

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

    # Refresh Apply button state
    self.onSelect()
Example #29
0
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        # Instantiate and connect widgets ...

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

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

        #
        # input selector
        #

        # File dialog to select a file template for series
        self.inputFileSelector = ctk.ctkPathLineEdit()
        self.inputFileSelector.filters = ctk.ctkPathLineEdit().Files
        self.inputFileSelector.setToolTip(
            "Select log file from a directory of images.")
        parametersFormLayout.addRow("Select log file from image series:",
                                    self.inputFileSelector)

        #
        # output volume selector
        #
        # self.outputSelector = slicer.qMRMLNodeComboBox()
        # self.outputSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"]
        # self.outputSelector.selectNodeUponCreation = True
        # self.outputSelector.addEnabled = True
        # self.outputSelector.removeEnabled = True
        # self.outputSelector.noneEnabled = True
        # self.outputSelector.showHidden = False
        # self.outputSelector.showChildNodeTypes = False
        # self.outputSelector.renameEnabled = True
        # self.outputSelector.setMRMLScene( slicer.mrmlScene )
        # self.outputSelector.setToolTip( "Pick the output to the algorithm." )
        # parametersFormLayout.addRow("Output Volume: ", self.outputSelector)

        #
        # check box to trigger taking screen shots for later use in tutorials
        #
        self.enableScreenshotsFlagCheckBox = qt.QCheckBox()
        self.enableScreenshotsFlagCheckBox.checked = 0
        self.enableScreenshotsFlagCheckBox.setToolTip(
            "If checked, take screen shots for tutorials. Use Save Data to write them to disk."
        )
        parametersFormLayout.addRow("Enable Screenshots",
                                    self.enableScreenshotsFlagCheckBox)

        #
        # Apply Button
        #
        self.applyButton = qt.QPushButton("Apply")
        self.applyButton.toolTip = "Run the algorithm."
        self.applyButton.enabled = False
        parametersFormLayout.addRow(self.applyButton)

        # connections
        self.applyButton.connect('clicked(bool)', self.onApplyButton)
        #self.outputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect)
        self.inputFileSelector.connect("currentPathChanged(const QString &)",
                                       self.onSelect)

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

        # Refresh Apply button state
        self.onSelect()
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        # Instantiate and connect widgets ...

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

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

        #
        # Select landmark file to import
        #
        self.inputFileSelector = ctk.ctkPathLineEdit()
        self.inputFileSelector.setToolTip(
            "Select Morphologika landmark file for conversion")
        parametersFormLayout.addRow(
            "Select file containing landmark names and coordinates to load:",
            self.inputFileSelector)

        #
        # output directory selector
        #
        self.outputDirectory = ctk.ctkDirectoryButton()
        self.outputDirectory.directory = qt.QDir.homePath()
        parametersFormLayout.addRow("Output Directory:", self.outputDirectory)

        #
        # check box to trigger taking screen shots for later use in tutorials
        #
        self.enableScreenshotsFlagCheckBox = qt.QCheckBox()
        self.enableScreenshotsFlagCheckBox.checked = 0
        self.enableScreenshotsFlagCheckBox.setToolTip(
            "If checked, take screen shots for tutorials. Use Save Data to write them to disk."
        )
        parametersFormLayout.addRow("Enable Screenshots",
                                    self.enableScreenshotsFlagCheckBox)

        #
        # Apply Button
        #
        self.applyButton = qt.QPushButton("Apply")
        self.applyButton.toolTip = "Run the conversion."
        self.applyButton.enabled = False
        parametersFormLayout.addRow(self.applyButton)

        # connections
        self.applyButton.connect('clicked(bool)', self.onApplyButton)
        self.inputFileSelector.connect('validInputChanged(bool)',
                                       self.onSelectInput)

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

        # Refresh Apply button state
        self.onSelectInput()
  def setup(self):
    ScriptedLoadableModuleWidget.setup(self)
    self.logic = Collect_Training_ImagesLogic()

    self.moduleDir = os.path.dirname(slicer.modules.collect_training_images.path)

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

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

    #self.imageSaveDirectory = qt.QLineEdit("Select directory to save images")
    #parametersFormLayout.addRow(self.imageSaveDirectory)

    self.modelSelector = qt.QComboBox()
    self.modelSelector.addItems(["Select model"])
    modelDirectoryContents = os.listdir(os.path.join(self.moduleDir,os.pardir,"Models"))
    modelNames = [dir for dir in modelDirectoryContents if dir.find(".") == -1 and dir != "Dockerfile"]
    self.modelSelector.addItems(["Create new model"])
    self.modelSelector.addItems(modelNames)
    parametersFormLayout.addRow(self.modelSelector)

    #self.imageSaveDirectoryLabel = qt.QLabel("Training photo directory:")
    #parametersFormLayout.addRow(self.imageSaveDirectoryLabel)

    self.imageSaveDirectoryLineEdit = ctk.ctkPathLineEdit()
    #node = self.logic.getParameterNode()
    imageSaveDirectory = os.path.dirname(slicer.modules.collect_training_images.path)
    self.imageSaveDirectoryLineEdit.currentPath = imageSaveDirectory
    self.imageSaveDirectoryLineEdit.filters = ctk.ctkPathLineEdit.Dirs
    self.imageSaveDirectoryLineEdit.options = ctk.ctkPathLineEdit.DontUseSheet
    self.imageSaveDirectoryLineEdit.options = ctk.ctkPathLineEdit.ShowDirsOnly
    self.imageSaveDirectoryLineEdit.showHistoryButton = False
    self.imageSaveDirectoryLineEdit.setMinimumWidth(100)
    self.imageSaveDirectoryLineEdit.setMaximumWidth(500)
    #parametersFormLayout.addRow(self.imageSaveDirectoryLineEdit)

    self.imageClassComboBox = qt.QComboBox()
    self.imageClassComboBox.addItems(["Select image class","Create new image class"])

    parametersFormLayout.addRow(self.imageClassComboBox)

    #
    # Start/Stop Image Collection Button
    #
    self.startStopCollectingImagesButton = qt.QPushButton("Start Image Collection")
    self.startStopCollectingImagesButton.toolTip = "Collect training images."
    self.startStopCollectingImagesButton.enabled = False
    parametersFormLayout.addRow(self.startStopCollectingImagesButton)


    self.infoLabel = qt.QLabel("")
    parametersFormLayout.addRow(self.infoLabel)

    # connections
    self.modelSelector.connect('currentIndexChanged(int)',self.onModelSelected)
    self.startStopCollectingImagesButton.connect('clicked(bool)', self.onStartStopCollectingImagesButton)
    self.imageClassComboBox.connect('currentIndexChanged(int)',self.onImageClassSelected)

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

    # Refresh Start/Stop Collecting Images Button state
    self.onSelect()
    try:
      self.webcamReference = slicer.util.getNode('Webcam_Reference')
    except slicer.util.MRMLNodeNotFoundException:
    #if not self.webcamReference:
      imageSpacing = [0.2, 0.2, 0.2]
      imageData = vtk.vtkImageData()
      imageData.SetDimensions(640, 480, 1)
      imageData.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 1)
      thresholder = vtk.vtkImageThreshold()
      thresholder.SetInputData(imageData)
      thresholder.SetInValue(0)
      thresholder.SetOutValue(0)
      # Create volume node
      self.webcamReference = slicer.vtkMRMLVectorVolumeNode()
      self.webcamReference.SetName('Webcam_Reference')
      self.webcamReference.SetSpacing(imageSpacing)
      self.webcamReference.SetImageDataConnection(thresholder.GetOutputPort())
      # Add volume to scene
      slicer.mrmlScene.AddNode(self.webcamReference)
      displayNode = slicer.vtkMRMLVectorVolumeDisplayNode()
      slicer.mrmlScene.AddNode(displayNode)
      self.webcamReference.SetAndObserveDisplayNodeID(displayNode.GetID())

    self.webcamConnectorNode = self.createWebcamPlusConnector()
    self.webcamConnectorNode.Start()
    self.setupWebcamResliceDriver()
Example #32
0
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        # Instantiate and connect widgets ...
        #
        # Parameters Area
        #
        parametersCollapsibleButton = ctk.ctkCollapsibleButton()
        parametersCollapsibleButton.text = "Parameters"
        self.layout.addWidget(parametersCollapsibleButton)

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

        #
        # Select base mesh
        #
        self.modelSelector = slicer.qMRMLNodeComboBox()
        self.modelSelector.nodeTypes = (("vtkMRMLModelNode"), "")
        self.modelSelector.selectNodeUponCreation = False
        self.modelSelector.addEnabled = False
        self.modelSelector.removeEnabled = False
        self.modelSelector.noneEnabled = True
        self.modelSelector.showHidden = False
        self.modelSelector.setMRMLScene(slicer.mrmlScene)
        parametersFormLayout.addRow("Base mesh: ", self.modelSelector)

        #
        # Select base landmark file
        #
        #self.baseLMFile=ctk.ctkPathLineEdit()
        #self.baseLMFile.setToolTip( "Select file specifying base landmarks" )
        #parametersFormLayout.addRow("Base landmark file: ", self.baseLMFile)
        self.baseLMSelect = slicer.qMRMLNodeComboBox()
        self.baseLMSelect.nodeTypes = (('vtkMRMLMarkupsFiducialNode'), "")
        self.baseLMSelect.selectNodeUponCreation = False
        self.baseLMSelect.addEnabled = False
        self.baseLMSelect.removeEnabled = False
        self.baseLMSelect.noneEnabled = True
        self.baseLMSelect.showHidden = False
        self.baseLMSelect.showChildNodeTypes = False
        self.baseLMSelect.setMRMLScene(slicer.mrmlScene)
        parametersFormLayout.addRow("Base landmarks: ", self.baseLMSelect)

        #
        # Select base semi-landmark file
        #
        #self.baseLMFile=ctk.ctkPathLineEdit()
        #self.baseLMFile.setToolTip( "Select file specifying base landmarks" )
        #parametersFormLayout.addRow("Base landmark file: ", self.baseLMFile)
        self.baseSLMSelect = slicer.qMRMLNodeComboBox()
        self.baseSLMSelect.nodeTypes = (('vtkMRMLMarkupsFiducialNode'), "")
        self.baseSLMSelect.selectNodeUponCreation = False
        self.baseSLMSelect.addEnabled = False
        self.baseSLMSelect.removeEnabled = False
        self.baseSLMSelect.noneEnabled = True
        self.baseSLMSelect.showHidden = False
        self.baseSLMSelect.showChildNodeTypes = False
        self.baseSLMSelect.setMRMLScene(slicer.mrmlScene)
        parametersFormLayout.addRow("Base semi-landmarks: ",
                                    self.baseSLMSelect)

        #
        # Select meshes directory
        #
        self.meshDirectory = ctk.ctkPathLineEdit()
        self.meshDirectory.filters = ctk.ctkPathLineEdit.Dirs
        self.meshDirectory.setToolTip("Select directory containing meshes")
        parametersFormLayout.addRow("Mesh directory: ", self.meshDirectory)

        #
        # Select landmarks directory
        #
        self.landmarkDirectory = ctk.ctkPathLineEdit()
        self.landmarkDirectory.filters = ctk.ctkPathLineEdit.Dirs
        self.landmarkDirectory.setToolTip(
            "Select directory containing landmarks")
        parametersFormLayout.addRow("Landmark directory: ",
                                    self.landmarkDirectory)

        #
        # Select semi-landmarks directory
        #
        self.semilandmarkDirectory = ctk.ctkPathLineEdit()
        self.semilandmarkDirectory.filters = ctk.ctkPathLineEdit.Dirs
        self.semilandmarkDirectory.setToolTip(
            "Select directory containing semi-landmarks")
        self.semilandmarkDirectory.enabled = False
        parametersFormLayout.addRow("Semi-landmark directory: ",
                                    self.semilandmarkDirectory)

        #
        # Select output directory
        #
        self.outputDirectory = ctk.ctkPathLineEdit()
        self.outputDirectory.filters = ctk.ctkPathLineEdit.Dirs
        self.outputDirectory.currentPath = slicer.app.temporaryPath
        self.outputDirectory.setToolTip(
            "Select directory to save output distance maps")
        parametersFormLayout.addRow("Output directory: ", self.outputDirectory)

        #
        # Select distance metric
        #
        self.unSignedDistanceOption = qt.QRadioButton()
        self.unSignedDistanceOption.setChecked(True)
        parametersFormLayout.addRow("Unsigned Distance: ",
                                    self.unSignedDistanceOption)
        self.signedDistanceOption = qt.QRadioButton()
        self.signedDistanceOption.setChecked(False)
        parametersFormLayout.addRow("Signed Distance: ",
                                    self.signedDistanceOption)

        #
        # Apply Button
        #
        self.applyButton = qt.QPushButton("Apply")
        self.applyButton.toolTip = "Generate MeshDistanceMeasurements."
        self.applyButton.enabled = False
        parametersFormLayout.addRow(self.applyButton)

        # connections
        self.modelSelector.connect('currentNodeChanged(vtkMRMLNode*)',
                                   self.onSelect)
        self.baseLMSelect.connect('currentNodeChanged(vtkMRMLNode*)',
                                  self.onSelect)
        self.meshDirectory.connect('validInputChanged(bool)', self.onSelect)
        self.baseSLMSelect.connect('currentNodeChanged(bool)',
                                   self.onSelectBaseSLM)
        self.semilandmarkDirectory.connect('validInputChanged(bool)',
                                           self.onSelect)

        self.applyButton.connect('clicked(bool)', self.onApplyButton)

        # Add vertical spacer
        self.layout.addStretch(1)
Example #33
0
  def setup(self):
    ScriptedLoadableModuleWidget.setup(self)

    self.logic = SegmentMesherLogic()
    self.logic.logCallback = self.addLog
    self.modelGenerationInProgress = False

    # Instantiate and connect widgets ...

    # Parameter sets
    defaultinputParametersCollapsibleButton = ctk.ctkCollapsibleButton()
    defaultinputParametersCollapsibleButton.text = "Parameter set"
    defaultinputParametersCollapsibleButton.collapsed = True
    self.layout.addWidget(defaultinputParametersCollapsibleButton)
    defaultParametersLayout = qt.QFormLayout(defaultinputParametersCollapsibleButton)

    self.parameterNodeSelector = slicer.qMRMLNodeComboBox()
    self.parameterNodeSelector.nodeTypes = ["vtkMRMLScriptedModuleNode"]
    self.parameterNodeSelector.addAttribute( "vtkMRMLScriptedModuleNode", "ModuleName", "SegmentMesher" )
    self.parameterNodeSelector.selectNodeUponCreation = True
    self.parameterNodeSelector.addEnabled = True
    self.parameterNodeSelector.renameEnabled = True
    self.parameterNodeSelector.removeEnabled = True
    self.parameterNodeSelector.noneEnabled = False
    self.parameterNodeSelector.showHidden = True
    self.parameterNodeSelector.showChildNodeTypes = False
    self.parameterNodeSelector.baseName = "SegmentMesher"
    self.parameterNodeSelector.setMRMLScene( slicer.mrmlScene )
    self.parameterNodeSelector.setToolTip( "Pick parameter set" )
    defaultParametersLayout.addRow("Parameter set: ", self.parameterNodeSelector)

    #
    # Inputs
    #
    inputParametersCollapsibleButton = ctk.ctkCollapsibleButton()
    inputParametersCollapsibleButton.text = "Inputs"
    self.layout.addWidget(inputParametersCollapsibleButton)

    # Layout within the dummy collapsible button
    inputParametersFormLayout = qt.QFormLayout(inputParametersCollapsibleButton)

    self.inputModelSelector = slicer.qMRMLNodeComboBox()
    self.inputModelSelector.nodeTypes = ["vtkMRMLSegmentationNode"]
    self.inputModelSelector.selectNodeUponCreation = True
    self.inputModelSelector.addEnabled = False
    self.inputModelSelector.removeEnabled = False
    self.inputModelSelector.noneEnabled = False
    self.inputModelSelector.showHidden = False
    self.inputModelSelector.showChildNodeTypes = False
    self.inputModelSelector.setMRMLScene( slicer.mrmlScene )
    self.inputModelSelector.setToolTip( "Volumetric mesh will be generated for all visible segments in this segmentation node." )
    inputParametersFormLayout.addRow("Input segmentation: ", self.inputModelSelector)


    self.methodSelectorComboBox = qt.QComboBox()
    self.methodSelectorComboBox.addItem("Cleaver", METHOD_CLEAVER)
    self.methodSelectorComboBox.addItem("TetGen", METHOD_TETGEN)
    inputParametersFormLayout.addRow("Meshing method: ", self.methodSelectorComboBox)

    #
    # Outputs
    #
    outputParametersCollapsibleButton = ctk.ctkCollapsibleButton()
    outputParametersCollapsibleButton.text = "Outputs"
    self.layout.addWidget(outputParametersCollapsibleButton)
    outputParametersFormLayout = qt.QFormLayout(outputParametersCollapsibleButton)

    #
    # output volume selector
    #
    self.outputModelSelector = slicer.qMRMLNodeComboBox()
    self.outputModelSelector.nodeTypes = ["vtkMRMLModelNode"]
    self.outputModelSelector.selectNodeUponCreation = True
    self.outputModelSelector.addEnabled = True
    self.outputModelSelector.renameEnabled = True
    self.outputModelSelector.removeEnabled = True
    self.outputModelSelector.noneEnabled = False
    self.outputModelSelector.showHidden = False
    self.outputModelSelector.showChildNodeTypes = False
    self.outputModelSelector.setMRMLScene( slicer.mrmlScene )
    self.outputModelSelector.setToolTip( "Created volumetric mesh" )
    outputParametersFormLayout.addRow("Output model: ", self.outputModelSelector)

    #
    # Advanced area
    #
    self.advancedCollapsibleButton = ctk.ctkCollapsibleButton()
    self.advancedCollapsibleButton.text = "Advanced"
    self.advancedCollapsibleButton.collapsed = True
    self.layout.addWidget(self.advancedCollapsibleButton)
    advancedFormLayout = qt.QFormLayout(self.advancedCollapsibleButton)

    self.cleaverAdditionalParametersWidget = qt.QLineEdit()
    self.cleaverAdditionalParametersWidget.setToolTip('Increase --scale parameter value to generate a finer resolution mesh. See description of all parameters in module documentation (Help & Acknowledgment section).')
    advancedFormLayout.addRow("Cleaver meshing options:", self.cleaverAdditionalParametersWidget)
    self.cleaverAdditionalParametersWidget.text = "--scale 0.2 --multiplier 2 --grading 5"

    self.cleaverRemoveBackgroundMeshCheckBox = qt.QCheckBox(" ")
    self.cleaverRemoveBackgroundMeshCheckBox.checked = True
    self.cleaverRemoveBackgroundMeshCheckBox.setToolTip("Remove background mesh (filling segmentation reference geometry box).")
    advancedFormLayout.addRow("Cleaver remove background mesh:", self.cleaverRemoveBackgroundMeshCheckBox)

    self.cleaverPaddingPercentSpinBox = qt.QSpinBox()
    self.cleaverPaddingPercentSpinBox.maximum = 200
    self.cleaverPaddingPercentSpinBox.value = 10
    self.cleaverPaddingPercentSpinBox.suffix=" %"
    self.cleaverPaddingPercentSpinBox.setToolTip("Add padding around the segments to ensure some minimum thickness to the background mesh. Increase value if segments have extrusions towards the edge of the padded bounding box.")
    advancedFormLayout.addRow("Cleaver background padding:", self.cleaverPaddingPercentSpinBox)

    customCleaverPath = self.logic.getCustomCleaverPath()
    self.customCleaverPathSelector = ctk.ctkPathLineEdit()
    self.customCleaverPathSelector.setCurrentPath(customCleaverPath)
    self.customCleaverPathSelector.nameFilters = [self.logic.cleaverFilename]
    self.customCleaverPathSelector.setSizePolicy(qt.QSizePolicy.MinimumExpanding, qt.QSizePolicy.Preferred)
    self.customCleaverPathSelector.setToolTip("Set cleaver-cli executable path. "
      "If value is empty then cleaver-cli bundled with this extension will be used.")
    advancedFormLayout.addRow("Custom Cleaver executable path:", self.customCleaverPathSelector)

    self.tetGenAdditionalParametersWidget = qt.QLineEdit()
    self.tetGenAdditionalParametersWidget.setToolTip('See description of parameters in module documentation (Help & Acknowledgment section).')
    advancedFormLayout.addRow("TetGen meshing options:", self.tetGenAdditionalParametersWidget)
    self.tetGenAdditionalParametersWidget.text = ""

    customTetGenPath = self.logic.getCustomTetGenPath()
    self.customTetGenPathSelector = ctk.ctkPathLineEdit()
    self.customTetGenPathSelector.setCurrentPath(customTetGenPath)
    self.customTetGenPathSelector.nameFilters = [self.logic.tetGenFilename]
    self.customTetGenPathSelector.setSizePolicy(qt.QSizePolicy.MinimumExpanding, qt.QSizePolicy.Preferred)
    self.customTetGenPathSelector.setToolTip("Set tetgen executable path. "
      "If value is empty then tetgen bundled with this extension will be used.")
    advancedFormLayout.addRow("Custom TetGen executable path:", self.customTetGenPathSelector)

    self.showDetailedLogDuringExecutionCheckBox = qt.QCheckBox(" ")
    self.showDetailedLogDuringExecutionCheckBox.checked = False
    self.showDetailedLogDuringExecutionCheckBox.setToolTip("Show detailed log during model generation.")
    advancedFormLayout.addRow("Show detailed log:", self.showDetailedLogDuringExecutionCheckBox)

    self.keepTemporaryFilesCheckBox = qt.QCheckBox(" ")
    self.keepTemporaryFilesCheckBox.checked = False
    self.keepTemporaryFilesCheckBox.setToolTip("Keep temporary files (inputs, computed outputs, logs) after the model generation is completed.")

    self.showTemporaryFilesFolderButton = qt.QPushButton("Show temp folder")
    self.showTemporaryFilesFolderButton.toolTip = "Open the folder where temporary files are stored."
    self.showTemporaryFilesFolderButton.setSizePolicy(qt.QSizePolicy.MinimumExpanding, qt.QSizePolicy.Preferred)

    hbox = qt.QHBoxLayout()
    hbox.addWidget(self.keepTemporaryFilesCheckBox)
    hbox.addWidget(self.showTemporaryFilesFolderButton)
    advancedFormLayout.addRow("Keep temporary files:", hbox)

    #
    # Display
    #
    displayParametersCollapsibleButton = ctk.ctkCollapsibleButton()
    displayParametersCollapsibleButton.text = "Display"
    displayParametersCollapsibleButton.collapsed = True
    self.layout.addWidget(displayParametersCollapsibleButton)
    displayParametersFormLayout = qt.QFormLayout(displayParametersCollapsibleButton)

    self.clipNodeWidget=slicer.qMRMLClipNodeWidget()
    clipNode = slicer.mrmlScene.GetFirstNodeByClass("vtkMRMLClipModelsNode")
    self.clipNodeWidget.setMRMLClipNode(clipNode)
    displayParametersFormLayout.addRow(self.clipNodeWidget)

    #
    # Apply Button
    #
    self.applyButton = qt.QPushButton("Apply")
    self.applyButton.toolTip = "Run the algorithm."
    self.applyButton.enabled = False
    self.layout.addWidget(self.applyButton)

    self.statusLabel = qt.QPlainTextEdit()
    self.statusLabel.setTextInteractionFlags(qt.Qt.TextSelectableByMouse)
    self.statusLabel.setCenterOnScroll(True)
    self.layout.addWidget(self.statusLabel)

    # connections
    self.applyButton.connect('clicked(bool)', self.onApplyButton)
    self.showTemporaryFilesFolderButton.connect('clicked(bool)', self.onShowTemporaryFilesFolder)
    self.inputModelSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.updateMRMLFromGUI)
    self.outputModelSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.updateMRMLFromGUI)
    self.methodSelectorComboBox.connect("currentIndexChanged(int)", self.updateMRMLFromGUI)
    # Immediately update deleteTemporaryFiles in the logic to make it possible to decide to
    # keep the temporary file while the model generation is running
    self.keepTemporaryFilesCheckBox.connect("toggled(bool)", self.onKeepTemporaryFilesToggled)

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

    # Refresh Apply button state
    self.updateMRMLFromGUI()
Example #34
0
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        # Instantiate and connect widgets ...

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

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

        self.meshDirectory = ctk.ctkPathLineEdit()
        self.meshDirectory.filters = ctk.ctkPathLineEdit.Dirs
        self.meshDirectory.setToolTip("Select directory containing landmarks")
        parametersFormLayout.addRow("Mesh directory: ", self.meshDirectory)

        self.landmarkDirectory = ctk.ctkPathLineEdit()
        self.landmarkDirectory.filters = ctk.ctkPathLineEdit.Dirs
        self.landmarkDirectory.setToolTip("Select directory containing meshes")
        parametersFormLayout.addRow("Landmark directory: ",
                                    self.landmarkDirectory)

        self.gridFile = ctk.ctkPathLineEdit()
        self.gridFile.filters = ctk.ctkPathLineEdit().Files
        self.gridFile.setToolTip(
            "Select file specifying semi-landmark connectivity")
        parametersFormLayout.addRow("Grid connectivity file: ", self.gridFile)

        # Select output directory
        self.outputDirectory = ctk.ctkPathLineEdit()
        self.outputDirectory.filters = ctk.ctkPathLineEdit.Dirs
        self.outputDirectory.setToolTip("Select directory for output models: ")
        parametersFormLayout.addRow("Output directory: ", self.outputDirectory)

        #
        # set sample rate value
        #
        self.sampleRate = ctk.ctkDoubleSpinBox()
        self.sampleRate.singleStep = 1
        self.sampleRate.minimum = 1
        self.sampleRate.maximum = 100
        self.sampleRate.setDecimals(0)
        self.sampleRate.value = 10
        self.sampleRate.setToolTip(
            "Select sample rate for semi-landmark interpolation")
        parametersFormLayout.addRow("Sample rate for interpolation:",
                                    self.sampleRate)
        #
        # Apply Button
        #
        self.applyButton = qt.QPushButton("Apply")
        self.applyButton.toolTip = "Generate PlaceSemiLMPatchess."
        self.applyButton.enabled = False
        parametersFormLayout.addRow(self.applyButton)

        # connections
        self.meshDirectory.connect('validInputChanged(bool)', self.onSelect)
        self.landmarkDirectory.connect('validInputChanged(bool)',
                                       self.onSelect)
        self.gridFile.connect('validInputChanged(bool)', self.onSelect)
        self.outputDirectory.connect('validInputChanged(bool)', self.onSelect)
        self.applyButton.connect('clicked(bool)', self.onApplyButton)

        # Add vertical spacer
        self.layout.addStretch(1)
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        # Instantiate and connect widgets ...

        #
        # Reload and Test area
        #
        reloadCollapsibleButton = ctk.ctkCollapsibleButton()
        reloadCollapsibleButton.text = "Reload && Test"
        reloadFormLayout = qt.QFormLayout(reloadCollapsibleButton)
        # reload button
        # (use this during development, but remove it when delivering
        #  your module to users)
        self.reloadButton = qt.QPushButton("Reload")
        self.reloadButton.toolTip = "Reload this module."
        self.reloadButton.name = "Freehand3DUltrasound Reload"
        reloadFormLayout.addWidget(self.reloadButton)
        self.reloadButton.connect('clicked()', self.onReload)
        # uncomment the following line for debug/development.
        self.layout.addWidget(reloadCollapsibleButton)

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

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

        self.jsonFindingsPath = ctk.ctkPathLineEdit()
        self.jsonFindingsPath.currentPath = '/home/mehrtash/github/ProstateX/notebooks/findings.json'
        # self.dockerPath.setMaximumWidth(300)
        parametersFormLayout.addRow("Findings File Path:",
                                    self.jsonFindingsPath)

        #
        # Load Button
        #
        self.loadButton = qt.QPushButton("Load")
        self.loadButton.toolTip = "Run the algorithm."
        self.loadButton.enabled = False
        parametersFormLayout.addRow(self.loadButton)

        #
        # finding index
        #
        self.findingIndexSliderWidget = ctk.ctkSliderWidget()
        self.findingIndexSliderWidget.singleStep = 1
        self.findingIndexSliderWidget.minimum = 0
        self.findingIndexSliderWidget.maximum = 10
        self.findingIndexSliderWidget.setDecimals(0)
        self.findingIndexSliderWidget.enabled = False
        self.findingIndexSliderWidget.setToolTip(
            "Set threshold value for computing the output image. Voxels that have intensities lower than this value will set to zero."
        )

        parametersFormLayout.addRow("Finding Index: ",
                                    self.findingIndexSliderWidget)
        # zone line edit
        self.uidLineEdit = qt.QLineEdit()
        self.uidLineEdit.setReadOnly(True)
        parametersFormLayout.addRow("Zone:", self.uidLineEdit)

        # zone line edit
        self.zoneLineEdit = qt.QLineEdit()
        self.zoneLineEdit.setReadOnly(True)
        parametersFormLayout.addRow("Zone:", self.zoneLineEdit)

        # zone line edit
        self.clinSigLineEdit = qt.QLineEdit()
        self.clinSigLineEdit.setReadOnly(True)
        parametersFormLayout.addRow("Clinical Significance:",
                                    self.clinSigLineEdit)

        # connections
        self.loadButton.connect('clicked(bool)', self.onLoadButton)
        self.jsonFindingsPath.connect("currentPathChanged(QString)",
                                      self.onSelect)
        self.findingIndexSliderWidget.connect('valueChanged(double)',
                                              self.findingIndexChanged)

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

        # Refresh Load button state
        self.onSelect()