Beispiel #1
0
    def __init__(self, parent, name, **kwargs):
        BaseGraphicScan.__init__(self,
                                 parent,
                                 name,
                                 uifile='A2Scan.ui',
                                 cmd_name='a2scan',
                                 **kwargs)
        self.__points = []
        ####### INIT GUI #######
        aTable = self._widgetTree.child('__table')
        qt.QObject.connect(aTable, qt.SIGNAL('valueChanged(int,int)'),
                           self._valueChangedScanParam)
        aTable.setColumnReadOnly(4, True)

        intervals = self._widgetTree.child('__intervals')
        intervals.setValidator(qt.QIntValidator(intervals))
        qt.QObject.connect(intervals, qt.SIGNAL('returnPressed ()'),
                           self.__intervalsChanged)
        qt.QObject.connect(intervals, qt.SIGNAL('lostFocus()'),
                           self.__intervalsChanged)

        timeWidget = self._widgetTree.child('__time')
        timeWidget.setValidator(qt.QDoubleValidator(timeWidget))
Beispiel #2
0
    def set_beamline_setup(self, beamline_setup):
        self._beamline_setup = beamline_setup

        limits_dict = self._beamline_setup.get_acquisition_limit_values()

        if 'osc_range' in limits_dict:
            limits = tuple(map(float, limits_dict['osc_range'].split(',')))
            (lower, upper) = limits
            osc_start_validator = qt.QDoubleValidator(lower, upper, 4, self)
            osc_range_validator = qt.QDoubleValidator(lower, upper, 4, self)
        else:
            osc_start_validator = qt.QDoubleValidator(-10000, 10000, 4, self)
            osc_range_validator = qt.QDoubleValidator(-10000, 10000, 4, self)

        osc_start_ledit = self.acq_widget_layout.child('osc_start_ledit')
        self._acquisition_mib.bind_value_update('osc_start', osc_start_ledit,
                                                float, osc_start_validator)

        osc_range_ledit = self.acq_widget_layout.child('osc_range_ledit')
        self._acquisition_mib.bind_value_update('osc_range', osc_range_ledit,
                                                float, osc_range_validator)

        kappa_validator = qt.QDoubleValidator(0, 360, 2, self)
        kappa_ledit = self.acq_widget_layout.child('kappa_ledit')
        self._acquisition_mib.bind_value_update('kappa', kappa_ledit, float,
                                                kappa_validator)

        kappa_phi_validator = qt.QDoubleValidator(0, 360, 2, self)
        kappa_phi_ledit = self.acq_widget_layout.child('kappa_phi_ledit')
        self._acquisition_mib.bind_value_update('kappa_phi', kappa_phi_ledit,
                                                float, kappa_phi_validator)

        if 'exposure_time' in limits_dict:
            limits = tuple(map(float, limits_dict['exposure_time'].split(',')))
            (lower, upper) = limits
            exp_time_valdidator = qt.QDoubleValidator(lower, upper, 5, self)
        else:
            exp_time_valdidator = qt.QDoubleValidator(-0.003, 6000, 5, self)

        exp_time_ledit = self.acq_widget_layout.child('exp_time_ledit')
        self._acquisition_mib.bind_value_update('exp_time', exp_time_ledit,
                                                float, exp_time_valdidator)

        if 'number_of_images' in limits_dict:
            limits = tuple(map(int,
                               limits_dict['number_of_images'].split(',')))
            (lower, upper) = limits
            num_img_valdidator = qt.QIntValidator(lower, upper, self)
            first_img_valdidator = qt.QIntValidator(lower, upper, self)
        else:
            num_img_valdidator = qt.QIntValidator(1, 9999, self)
            first_img_valdidator = qt.QIntValidator(1, 9999, self)

        first_img_ledit = self.acq_widget_layout.child('first_image_ledit')
        self._acquisition_mib.bind_value_update('first_image', first_img_ledit,
                                                int, first_img_valdidator)

        num_img_ledit = self.acq_widget_layout.child('num_images_ledit')
        self._acquisition_mib.bind_value_update('num_images', num_img_ledit,
                                                int, num_img_valdidator)

        num_passes = self.acq_widget_layout.child('num_passes_ledit')

        if num_passes:
            self._acquisition_mib.\
                bind_value_update('num_passes', num_passes, int,
                                  qt.QIntValidator(1, 1000, self))

        overlap_ledit = self.acq_widget_layout.child('overlap_ledit')

        if overlap_ledit:
            self._acquisition_mib.\
                bind_value_update('overlap', overlap_ledit, float,
                                  qt.QDoubleValidator(-1000, 1000, 2, self))

        self._acquisition_mib.\
             bind_value_update('energy',
                               self.acq_widget_layout.child('energy_ledit'),
                               float,
                               qt.QDoubleValidator(0, 1000, 4, self))

        self._acquisition_mib.\
             bind_value_update('transmission',
                            self.acq_widget_layout.child('transmission_ledit'),
                            float,
                            qt.QDoubleValidator(0, 1000, 2, self))

        self._acquisition_mib.\
             bind_value_update('resolution',
                               self.acq_widget_layout.child('resolution_ledit'),
                               float,
                               qt.QDoubleValidator(0, 1000, 3, self))

        self._acquisition_mib.\
             bind_value_update('inverse_beam',
                               self.acq_widget_layout.child('inverse_beam_cbx'),
                               bool,
                               None)

        self._acquisition_mib.\
             bind_value_update('shutterless',
                               self.acq_widget_layout.child('shutterless_cbx'),
                               bool,
                               None)

        te = beamline_setup.tunable_wavelength()
        self.set_tunable_energy(te)

        has_shutter_less = self._beamline_setup.detector_has_shutterless()
        self.acq_widget_layout.child('shutterless_cbx').\
             setEnabled(has_shutter_less)
        self.acq_widget_layout.child('shutterless_cbx').setChecked(
            has_shutter_less)

        if self._beamline_setup.disable_num_passes():
            num_passes = self.acq_widget_layout.child('num_passes_ledit')
            if num_passes:
                self.acq_widget_layout.child('num_passes_ledit').setDisabled(
                    True)

        has_aperture = self._beamline_setup.has_aperture()
        self.hide_aperture(has_aperture)
Beispiel #3
0
    def set_beamline_setup(self, beamline_setup):
        self._beamline_setup = beamline_setup

        limits_dict = self._beamline_setup.get_acquisition_limit_values()

        if "osc_range" in limits_dict:
            limits = tuple(map(float, limits_dict["osc_range"].split(",")))
            (lower, upper) = limits
            osc_start_validator = qt.QDoubleValidator(lower, upper, 4, self)
            osc_range_validator = qt.QDoubleValidator(lower, upper, 4, self)
        else:
            osc_start_validator = qt.QDoubleValidator(-10000, 10000, 4, self)
            osc_range_validator = qt.QDoubleValidator(-10000, 10000, 4, self)

        osc_start_ledit = self.acq_widget_layout.child("osc_start_ledit")
        self._acquisition_mib.bind_value_update(
            "osc_start", osc_start_ledit, float, osc_start_validator
        )

        osc_range_ledit = self.acq_widget_layout.child("osc_range_ledit")
        self._acquisition_mib.bind_value_update(
            "osc_range", osc_range_ledit, float, osc_range_validator
        )

        kappa_validator = qt.QDoubleValidator(0, 360, 2, self)
        kappa_ledit = self.acq_widget_layout.child("kappa_ledit")
        self._acquisition_mib.bind_value_update(
            "kappa", kappa_ledit, float, kappa_validator
        )

        kappa_phi_validator = qt.QDoubleValidator(0, 360, 2, self)
        kappa_phi_ledit = self.acq_widget_layout.child("kappa_phi_ledit")
        self._acquisition_mib.bind_value_update(
            "kappa_phi", kappa_phi_ledit, float, kappa_phi_validator
        )

        if "exposure_time" in limits_dict:
            limits = tuple(map(float, limits_dict["exposure_time"].split(",")))
            (lower, upper) = limits
            exp_time_valdidator = qt.QDoubleValidator(lower, upper, 5, self)
        else:
            exp_time_valdidator = qt.QDoubleValidator(-0.003, 6000, 5, self)

        exp_time_ledit = self.acq_widget_layout.child("exp_time_ledit")
        self._acquisition_mib.bind_value_update(
            "exp_time", exp_time_ledit, float, exp_time_valdidator
        )

        if "number_of_images" in limits_dict:
            limits = tuple(map(int, limits_dict["number_of_images"].split(",")))
            (lower, upper) = limits
            num_img_valdidator = qt.QIntValidator(lower, upper, self)
            first_img_valdidator = qt.QIntValidator(lower, upper, self)
        else:
            num_img_valdidator = qt.QIntValidator(1, 9999, self)
            first_img_valdidator = qt.QIntValidator(1, 9999, self)

        first_img_ledit = self.acq_widget_layout.child("first_image_ledit")
        self._acquisition_mib.bind_value_update(
            "first_image", first_img_ledit, int, first_img_valdidator
        )

        num_img_ledit = self.acq_widget_layout.child("num_images_ledit")
        self._acquisition_mib.bind_value_update(
            "num_images", num_img_ledit, int, num_img_valdidator
        )

        num_passes = self.acq_widget_layout.child("num_passes_ledit")

        if num_passes:
            self._acquisition_mib.bind_value_update(
                "num_passes", num_passes, int, qt.QIntValidator(1, 1000, self)
            )

        overlap_ledit = self.acq_widget_layout.child("overlap_ledit")

        if overlap_ledit:
            self._acquisition_mib.bind_value_update(
                "overlap",
                overlap_ledit,
                float,
                qt.QDoubleValidator(-1000, 1000, 2, self),
            )

        self._acquisition_mib.bind_value_update(
            "energy",
            self.acq_widget_layout.child("energy_ledit"),
            float,
            qt.QDoubleValidator(0, 1000, 4, self),
        )

        self._acquisition_mib.bind_value_update(
            "transmission",
            self.acq_widget_layout.child("transmission_ledit"),
            float,
            qt.QDoubleValidator(0, 1000, 2, self),
        )

        self._acquisition_mib.bind_value_update(
            "resolution",
            self.acq_widget_layout.child("resolution_ledit"),
            float,
            qt.QDoubleValidator(0, 1000, 3, self),
        )

        self._acquisition_mib.bind_value_update(
            "inverse_beam", self.acq_widget_layout.child("inverse_beam_cbx"), bool, None
        )

        self._acquisition_mib.bind_value_update(
            "shutterless", self.acq_widget_layout.child("shutterless_cbx"), bool, None
        )

        te = beamline_setup.tunable_wavelength()
        self.set_tunable_energy(te)

        has_shutter_less = self._beamline_setup.detector_has_shutterless()
        self.acq_widget_layout.child("shutterless_cbx").setEnabled(has_shutter_less)
        self.acq_widget_layout.child("shutterless_cbx").setChecked(has_shutter_less)

        if self._beamline_setup.disable_num_passes():
            num_passes = self.acq_widget_layout.child("num_passes_ledit")
            if num_passes:
                self.acq_widget_layout.child("num_passes_ledit").setDisabled(True)

        has_aperture = self._beamline_setup.has_aperture()
        self.hide_aperture(has_aperture)
    def setup(self):
        # this is the function that implements all GUI
        ScriptedLoadableModuleWidget.setup(self)

        # This sets the view being used to the red view only
        slicer.app.layoutManager().setLayout(
            slicer.vtkMRMLLayoutNode.SlicerLayoutOneUpRedSliceView)

        #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
        #Section 3.2.1: Ultrasound connection ang widgets
        #the following code provides a GUI to connect to an external ultrasound scanner throught the PlusServer
        #this section also provides examples of other widgets that can be used
        #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

        ##################################################################################################################
        #This section creates all the widgets
        #This is where you will create the type of widget and what it will say
        ##################################################################################################################

        #This code block creates a collapsible button

        #This defines which type of button you are using
        self.usButton = ctk.ctkCollapsibleButton()
        #This is what the button will say
        self.usButton.text = "Ultrasound Connection"
        #This actually creates that button

        #This descirbes the type of widget
        self.inputIPLineEdit = qt.QLineEdit()
        #This sets a placehoder example of what should be inputted to the line edit
        self.inputIPLineEdit.setPlaceholderText("127.0.0.1")
        #This is the help tooltip
        self.inputIPLineEdit.toolTip = "Put the IP address of your ultrasound device here"

        #This code block is the exact same as the one above only it asks for the server port
        self.inputPortLineEdit = qt.QLineEdit()
        self.inputPortLineEdit.setPlaceholderText("18944")
        self.inputPortLineEdit.setValidator(qt.QIntValidator())
        self.inputPortLineEdit.toolTip = "Put the port ID of the OpenIGTLink here (18944)"

        #This is a push button
        self.connectButton = qt.QPushButton()
        self.connectButton.setDefault(False)
        #This button says connect
        self.connectButton.text = "Connect"
        #help tooltip that explains the funciton
        self.connectButton.toolTip = "Connects to Ultrasound"
        #adds the widget to the layout

        self.freezeButton = qt.QPushButton()
        self.freezeButton.text = "Freeze"
        self.freezeButton.toolTip = "Freeze the ultrasound image for fiducial placement"

        # Combobox for image selection
        self.imageSelector = slicer.qMRMLNodeComboBox()
        self.imageSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"]
        self.imageSelector.selectNodeUponCreation = True
        self.imageSelector.addEnabled = False
        self.imageSelector.removeEnabled = False
        self.imageSelector.noneEnabled = True
        self.imageSelector.showHidden = False
        self.imageSelector.showChildNodeTypes = False
        self.imageSelector.setMRMLScene(slicer.mrmlScene)
        self.imageSelector.setToolTip("Pick the image to be used.")

        self.checkBox = qt.QCheckBox()
        self.checkBox.text = "This is a check box"
        self.checkBox.toolTip = "This an example check box"

        #### EXAMPLE: to access the functionality of a check box you can use an if statement
        #### if self.checkBox.isChecked() == True:

        self.radioButton = qt.QRadioButton()
        self.radioButton.text = "This is an example radio button"
        self.radioButton.toolTip = "This an example radio button"

        self.sliderWidget = slicer.qMRMLSliderWidget()
        self.sliderWidget.minimum = 0.00
        self.sliderWidget.maximum = 100.00

        self.resetButton = qt.QPushButton('Reset')
        self.resetButton.setDefault(False)
        self.resetButton.toolTip = "This Button Resets the Module"

        ##################################################################################################################
        #This section adds the containers to the parent widget
        ##################################################################################################################
        self.layout.addWidget(self.usButton)
        #This creates a variable that describes layout within this collapsible button
        self.usLayout = qt.QFormLayout(self.usButton)
        self.usLayout.addRow("Server IP:", self.inputIPLineEdit)
        self.usLayout.addRow("Server Port:", self.inputPortLineEdit)
        self.usLayout.addWidget(self.connectButton)
        self.usLayout.addRow("US Volume: ", self.imageSelector)
        self.usLayout.addRow(self.freezeButton)
        self.shortcut = qt.QShortcut(qt.QKeySequence('f'),
                                     slicer.util.mainWindow())
        self.usLayout.addRow(self.checkBox)
        self.usLayout.addRow(self.radioButton)
        self.usLayout.addRow(self.sliderWidget)

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

        ##################################################################################################################
        #This section connects the widgets to functions
        ##################################################################################################################
        self.connectButton.connect('clicked(bool)',
                                   self.onConnectButtonClicked)
        self.freezeButton.connect('clicked(bool)', self.onConnectButtonClicked)
        self.inputIPLineEdit.connect('textChanged(QString)',
                                     self.onInputChanged)
        self.inputPortLineEdit.connect('textChanged(QString)',
                                       self.onInputChanged)
        self.imageSelector.connect('currentNodeChanged(vtkMRMLNode*)',
                                   self.onImageChanged)

        # Disable buttons until conditions are met
        self.connectButton.setEnabled(False)
        self.freezeButton.setEnabled(False)
Beispiel #5
0
    def setup(self):
        """Init the widget """
        # self.firstLoad = True
        ScriptedLoadableModuleWidget.setup(self)
        self.disableEvents = False


        # Create objects that can be used anywhere in the module. Example: in most cases there should be just one
        # object of the logic class
        self._initLogic_()

        ##########
        # Main area
        self.mainAreaCollapsibleButton = ctk.ctkCollapsibleButton()
        self.mainAreaCollapsibleButton.text = "Main area"
        self.layout.addWidget(self.mainAreaCollapsibleButton, SlicerUtil.ALIGNMENT_VERTICAL_TOP)
        # self.layout.addWidget(self.mainAreaCollapsibleButton)
        # self.mainLayout = qt.QGridLayout(self.mainAreaCollapsibleButton)
        self.mainLayout = qt.QFormLayout(self.mainAreaCollapsibleButton)
        row = 0

        # Node selector
        volumeLabel = qt.QLabel("Active volume: ")
        volumeLabel.setStyleSheet("margin-left:5px")
        # self.mainLayout.addWidget(volumeLabel, row, 0)

        self.volumeSelector = slicer.qMRMLNodeComboBox()
        self.volumeSelector.nodeTypes = ("vtkMRMLScalarVolumeNode", "")
        self.volumeSelector.selectNodeUponCreation = True
        self.volumeSelector.autoFillBackground = True
        self.volumeSelector.addEnabled = False
        self.volumeSelector.noneEnabled = False
        self.volumeSelector.removeEnabled = False
        self.volumeSelector.showHidden = False
        self.volumeSelector.showChildNodeTypes = False
        self.volumeSelector.setMRMLScene(slicer.mrmlScene)
        self.volumeSelector.setMinimumWidth(150)
        # self.volumeSelector.setStyleSheet("margin: 15px 0")
        # self.volumeSelector.selectNodeUponCreation = False
        #self.mainLayout.addWidget(self.volumeSelector, row, 1)
        self.mainLayout.addRow(volumeLabel, self.volumeSelector)
        self.volumeSelector.connect('currentNodeChanged(vtkMRMLNode*)', self._onMainVolumeChanged_)

        row += 1
        lb = qt.QLabel("Click to select the calibration type and, if needed, modify the HU value expected for that area")
        lb.setStyleSheet("margin:10px 0 10px 5px")
        self.mainLayout.addRow(lb)
        #self.mainLayout.addWidget(lb, row, 0, 1, 2)

        self.typeRadioButtonGroup = qt.QButtonGroup()
        self.typeRadioButtonGroup.connect("buttonClicked (QAbstractButton*)", self.__onTypeRadioButtonClicked__)
        row += 1
        self.rbAir = qt.QRadioButton("Air")
        self.rbAir.setStyleSheet("margin-left:10px; margin-top: 5px")
        self.typeRadioButtonGroup.addButton(self.rbAir, 1)
        # self.mainLayout.addWidget(self.rbAir, row, 0)

        self.txtAir = qt.QLineEdit()
        self.txtAir.setText("-1000")
        self.txtAir.setFixedWidth(80)
        self.txtAir.setValidator(qt.QIntValidator())
        self.mainLayout.addRow(self.rbAir, self.txtAir)


        row += 1
        self.rbBlood = qt.QRadioButton("Blood")
        self.rbBlood.setStyleSheet("margin-left:10px; margin-top: 5px")
        self.typeRadioButtonGroup.addButton(self.rbBlood, 2)
        # self.mainLayout.addWidget(self.rbBlood, row, 0)

        self.txtBlood = qt.QLineEdit()
        self.txtBlood.setText("50")
        self.txtBlood.setFixedWidth(80)
        self.txtBlood.setValidator(qt.QIntValidator())
        # self.mainLayout.addWidget(self.txtBlood, row, 1)
        self.mainLayout.addRow(self.rbBlood, self.txtBlood)
        row += 1

        # Calibrate button
        self.calibrateButton = ctk.ctkPushButton()
        self.calibrateButton.setText("Calibrate")
        self.calibrateButton.toolTip = "Run the calibration"
        self.calibrateButton.setIcon(qt.QIcon("{0}/scale.png".format(SlicerUtil.CIP_ICON_DIR)))
        self.calibrateButton.setIconSize(qt.QSize(20, 20))
        self.calibrateButton.setFixedWidth(135)
        self.mainLayout.addRow(None, self.calibrateButton)
        self.calibrateButton.connect('clicked()', self._onCalibrateButtonClicked_)

        self._createEditorWidget_()
        self.setEditorValues()
Beispiel #6
0
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        # Connection

        connectionCollapsibleButton = ctk.ctkCollapsibleButton()
        connectionCollapsibleButton.text = "OSC server 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.addressRootLineEdit = qt.QLineEdit("SoundNav")
        self.addressRootLineEdit.setToolTip(
            "OSC address root. Complete address: /<address root>/<instrument name>/<parameter name>."
        )
        connectionFormLayout.addRow("Address root: ", self.addressRootLineEdit)

        self.enableConnectionCheckBox = qt.QCheckBox()
        self.enableConnectionCheckBox.checked = False
        self.enableConnectionCheckBox.setToolTip(
            "If checked, then transform changes will be immediately sent to specified OSC server."
        )
        connectionFormLayout.addRow("Transmission active: ",
                                    self.enableConnectionCheckBox)
        self.enableConnectionCheckBox.connect('stateChanged(int)',
                                              self.setTransmissionActive)

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

        parameterNode = self.logic.getParameterNode()

        maxNumberOfInstruments = int(
            parameterNode.GetParameter("MaxNumberOfInstruments"))
        for instrumentIndex in range(maxNumberOfInstruments):

            instrumentGroupBox = ctk.ctkCollapsibleGroupBox()
            instrumentGroupBox.title = "Instrument " + str(instrumentIndex + 1)
            parametersFormLayout.addWidget(instrumentGroupBox)
            instrumentLayout = qt.QFormLayout(instrumentGroupBox)

            nameLineEdit = qt.QLineEdit()
            instrumentLayout.addRow("Instrument name: ", nameLineEdit)
            nameLineEdit.connect('editingFinished()', self.updateMRMLFromGUI)

            instrumentSourceSelector = slicer.qMRMLNodeComboBox()

            instrumentNodeTypes = ["vtkMRMLLinearTransformNode"]
            if hasattr(slicer.modules, 'breachwarning'):
                instrumentNodeTypes.append("vtkMRMLBreachWarningNode")
            instrumentSourceSelector.nodeTypes = instrumentNodeTypes
            instrumentSourceSelector.addEnabled = True
            instrumentSourceSelector.removeEnabled = True
            instrumentSourceSelector.noneEnabled = True
            instrumentSourceSelector.renameEnabled = True
            instrumentSourceSelector.setMRMLScene(slicer.mrmlScene)
            instrumentSourceSelector.setToolTip(
                "Defines position and orientation of the instrument (transform or breach warning node)"
            )
            instrumentLayout.addRow("Instrument node: ",
                                    instrumentSourceSelector)
            instrumentSourceSelector.connect(
                "currentNodeChanged(vtkMRMLNode*)", self.updateMRMLFromGUI)

            instrumentReferenceSelector = slicer.qMRMLNodeComboBox()
            instrumentReferenceSelector.nodeTypes = [
                "vtkMRMLLinearTransformNode"
            ]
            instrumentReferenceSelector.addEnabled = True
            instrumentReferenceSelector.removeEnabled = True
            instrumentReferenceSelector.noneEnabled = True
            instrumentReferenceSelector.renameEnabled = True
            instrumentReferenceSelector.setMRMLScene(slicer.mrmlScene)
            instrumentReferenceSelector.setToolTip(
                "Position and orientation is defined relative to this transform"
            )
            instrumentLayout.addRow("Reference transform: ",
                                    instrumentReferenceSelector)
            instrumentReferenceSelector.connect(
                "currentNodeChanged(vtkMRMLNode*)", self.updateMRMLFromGUI)

            widgets = {}
            widgets['instrumentGroupBox'] = instrumentGroupBox
            widgets['nameLineEdit'] = nameLineEdit
            widgets['instrumentSourceSelector'] = instrumentSourceSelector
            widgets[
                'instrumentReferenceSelector'] = instrumentReferenceSelector

            self.instrumentWidgets.append(widgets)

        self.updateGUIFromMRML()

        self.hostnameLineEdit.connect('editingFinished()',
                                      self.updateMRMLFromGUI)
        self.portLineEdit.connect('editingFinished()', self.updateMRMLFromGUI)
        self.addressRootLineEdit.connect('editingFinished()',
                                         self.updateMRMLFromGUI)

        for instrumentIndex in range(len(self.instrumentWidgets)):
            widgets = self.instrumentWidgets[instrumentIndex]
            # Collapse unused instrument groupboxes
            widgets['instrumentGroupBox'].collapsed = not widgets[
                'nameLineEdit'].text
            # Observe widget changes to update MRML node immediately (this way always up-to-date values will be saved in the scene)
            widgets['nameLineEdit'].connect('editingFinished()',
                                            self.updateMRMLFromGUI)
            widgets['instrumentSourceSelector'].connect(
                "currentNodeChanged(vtkMRMLNode*)", self.updateMRMLFromGUI)
            widgets['instrumentReferenceSelector'].connect(
                "currentNodeChanged(vtkMRMLNode*)", self.updateMRMLFromGUI)

        self.parameterNodeObserverTag = parameterNode.AddObserver(
            vtk.vtkCommand.ModifiedEvent, self.updateGUIFromMRML)

        # 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)
Beispiel #8
0
  def setup(self):
    # this is the function that implements all GUI 
    ScriptedLoadableModuleWidget.setup(self)

    # This sets the view being used to the red view only 
    slicer.app.layoutManager().setLayout(slicer.vtkMRMLLayoutNode.SlicerLayoutOneUpRedSliceView)

    l = slicer.modules.createmodels.logic()
    self.needleModel = l.CreateNeedle(150, 0.4, 0, False)
    #This code block creates a collapsible button 
    #This defines which type of button you are using 
    self.usContainer = ctk.ctkCollapsibleButton()
    #This is what the button will say 
    self.usContainer.text = "Ultrasound Information"
    #Thiss actually creates that button
    self.layout.addWidget(self.usContainer)
    #This creates a variable that describes layout within this collapsible button 
    self.usLayout = qt.QFormLayout(self.usContainer)

    #This descirbes the type of widget 
    self.inputIPLineEdit = qt.QLineEdit()
    #This sets a placehoder example of what should be inputted to the line edit 
    self.inputIPLineEdit.setPlaceholderText("127.0.0.1")
    #This is the help tooltip 
    self.inputIPLineEdit.toolTip = "Put the IP address of your ultrasound device here"
    #This is the text that is input inot the line 
    self.IPLabel = qt.QLabel("Server IP:")
    if slicer.mrmlScene.GetNodesByClass("vtkMRMLSequenceNode").GetNumberOfItems() == 0:
      self.usLayout.addRow(self.IPLabel, self.inputIPLineEdit)

    #This code block is the exact same as the one above only it asks for the server port 
    self.layout.addWidget(self.usContainer)
    self.inputPortLineEdit = qt.QLineEdit()
    self.inputPortLineEdit.setPlaceholderText("18944")
    self.inputPortLineEdit.setValidator(qt.QIntValidator())
    self.inputPortLineEdit.toolTip = "Put the Port of your ultrasound device here"
    self.portLabel = qt.QLabel("Sever Port:")
    if slicer.mrmlScene.GetNodesByClass("vtkMRMLSequenceNode").GetNumberOfItems() == 0:
      self.usLayout.addRow(self.portLabel, self.inputPortLineEdit)

    #This is a push button 
    self.connectButton = qt.QPushButton()
    self.connectButton.setDefault(False)
    #This button says connect 
    self.connectButton.text = "Connect"
    #help tooltip that explains the funciton 
    self.connectButton.toolTip = "Connects to Ultrasound"
    #adds the widget to the layout 
    if slicer.mrmlScene.GetNodesByClass("vtkMRMLSequenceNode").GetNumberOfItems() == 0:
      self.usLayout.addWidget(self.connectButton)

    # Combobox for image selection
    self.imageSelector = slicer.qMRMLNodeComboBox()
    self.imageSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"]
    self.imageSelector.selectNodeUponCreation = True
    self.imageSelector.addEnabled = False
    self.imageSelector.removeEnabled = False
    self.imageSelector.noneEnabled = True
    self.imageSelector.showHidden = False
    self.imageSelector.showChildNodeTypes = False
    self.imageSelector.setMRMLScene( slicer.mrmlScene )
    self.imageSelector.setToolTip( "Pick the image to be used." )
    self.usLayout.addRow("US Volume: ", self.imageSelector)
    
    #add combo box for linear transform node 
    self.TransformSelector = slicer.qMRMLNodeComboBox()
    self.TransformSelector.nodeTypes = ["vtkMRMLLinearTransformNode"]
    self.TransformSelector.selectNodeUponCreation = True
    self.TransformSelector.addEnabled = False
    self.TransformSelector.removeEnabled = False
    self.TransformSelector.noneEnabled = True
    self.TransformSelector.showHidden = False
    self.TransformSelector.showChildNodeTypes = False
    self.TransformSelector.setMRMLScene( slicer.mrmlScene )
    self.TransformSelector.setToolTip( "Pick the transform representing the straw line." )
    self.usLayout.addRow("Tip to Probe: ", self.TransformSelector)
    
    self.calibrationContainer = ctk.ctkCollapsibleButton()
    #This is what the button will say 
    self.calibrationContainer.text = "Calibration Parameters"
    #Thiss actually creates that button
    self.layout.addWidget(self.calibrationContainer)
    #This creates a variable that describes layout within this collapsible button 
    self.calibrationLayout = qt.QFormLayout(self.calibrationContainer)
    
    self.segLabel = qt.QLabel()
    self.calibrationLayout.addRow(qt.QLabel("Type of segmentation:"), self.segLabel)
    
    self.recordContainer = ctk.ctkCollapsibleButton()
    #This is what the button will say 
    self.recordContainer.text = "Recording Options"
    #Thiss actually creates that button
    #This creates a variable that describes layout within this collapsible button 
    self.recordLayout = qt.QFormLayout(self.recordContainer)
    
    self.RecordButton = qt.QPushButton() 
    self.RecordButton.text = "Start Recording" 
    self.recordLayout.addWidget(self.RecordButton)
    
    self.StopRecordButton = qt.QPushButton() 
    self.StopRecordButton.text = "Stop Recording" 
    self.recordLayout.addWidget(self.StopRecordButton)
    
    self.pathInput = qt.QLineEdit()
    self.pathInput.setPlaceholderText("Enter the path to save files to")
    self.pathText = qt.QLabel("File Path:")
    self.recordLayout.addRow(self.pathText, self.pathInput)
    
    self.SaveRecordButton = qt.QPushButton() 
    self.SaveRecordButton.text = "Save Recording" 
    self.recordLayout.addWidget(self.SaveRecordButton)
    
    # This creates another collapsible button
    self.fiducialContainer = ctk.ctkCollapsibleButton()
    self.fiducialContainer.text = "Registration"

    self.fiducialLayout = qt.QFormLayout(self.fiducialContainer)

    #This is the exact same as the code block below but it freezes the US to capture a screenshot 
    self.freezeButton = qt.QPushButton()
    if slicer.mrmlScene.GetNodesByClass("vtkMRMLSequenceNode").GetNumberOfItems() == 0:
      self.freezeButton.text = "Freeze"
    else:
      self.freezeButton.text = "Place Fiducial"
    self.freezeButton.toolTip = "Freeze the ultrasound image for fiducial placement"
    self.fiducialLayout.addRow(self.freezeButton)
    self.shortcut = qt.QShortcut(qt.QKeySequence('f'), slicer.util.mainWindow())
    
    self.numFidLabel = qt.QLabel()
    self.fiducialLayout.addRow(qt.QLabel("Fiducials collected:"), self.numFidLabel)

    self.transformTable = qt.QTableWidget() 
    self.transTableItem = qt.QTableWidgetItem()
    self.fidError = qt.QLabel()
    self.transformTable.setRowCount(4)
    self.transformTable.setColumnCount(4)
    self.transformTable.horizontalHeader().hide()
    self.transformTable.verticalHeader().hide()
    self.transformTable.setItem(0,0, qt.QTableWidgetItem("1"))
    self.transformTable.setItem(0,1, qt.QTableWidgetItem("0"))
    self.transformTable.setItem(0,2, qt.QTableWidgetItem("0"))
    self.transformTable.setItem(0,3, qt.QTableWidgetItem("0"))
    self.transformTable.setItem(1,0, qt.QTableWidgetItem("0"))
    self.transformTable.setItem(1,1, qt.QTableWidgetItem("1"))
    self.transformTable.setItem(1,2, qt.QTableWidgetItem("0"))
    self.transformTable.setItem(1,3, qt.QTableWidgetItem("0"))
    self.transformTable.setItem(2,0, qt.QTableWidgetItem("0"))
    self.transformTable.setItem(2,1, qt.QTableWidgetItem("0"))
    self.transformTable.setItem(2,2, qt.QTableWidgetItem("1"))
    self.transformTable.setItem(2,3, qt.QTableWidgetItem("0"))
    self.transformTable.setItem(3,0, qt.QTableWidgetItem("0"))
    self.transformTable.setItem(3,1, qt.QTableWidgetItem("0"))
    self.transformTable.setItem(3,2, qt.QTableWidgetItem("0"))
    self.transformTable.setItem(3,3, qt.QTableWidgetItem("1"))
    self.transformTable.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.MinimumExpanding)
    self.copyIcon =qt.QIcon(":Icons/Medium/SlicerEditCopy.png")
    self.copyButton = qt.QPushButton()
    self.copyButton.setIcon(self.copyIcon)
    self.copyButton.toolTip = "Copy" 
    self.copyButton.setMaximumWidth(64)
    self.copyHbox = qt.QHBoxLayout()
    self.copyHbox.addWidget(self.copyButton)
    
    self.copyButton.enabled = False 
    if self.numFidLabel >= 2: 
      self.copyButton.enabled = True 
      
    self.fiducialLayout.addRow(qt.QLabel("Image to probe transform:"))
    self.fiducialLayout.addRow(self.transformTable)
         # Add vertical spacer
    self.layout.addStretch(1)
    
         # Add vertical spacer
    self.layout.addStretch(1)
    
    self.fiducialLayout.addRow("Copy:", self.copyHbox)
 

    self.validationContainer = ctk.ctkCollapsibleButton()
    self.validationContainer.text = "Validation"
    self.validationLayout = qt.QFormLayout(self.validationContainer)

    self.visualizeButton = qt.QPushButton('Show 3D Scene')
    self.visualizeButton.toolTip = "This button enables the 3D view for visual validation"
    self.validationLayout.addRow(self.visualizeButton)
    self.visualizeButton.connect('clicked(bool)', self.onVisualizeButtonClicked)


    self.resetButton = qt.QPushButton('Reset')
    self.resetButton.setDefault(False)
    self.resetButton.toolTip = "This Button Resets the Module"
    self.validationLayout.addRow(self.resetButton)

    # Add the containers to the parent
    self.layout.addWidget(self.usContainer)
    self.layout.addWidget(self.calibrationContainer)
    if slicer.mrmlScene.GetNodesByClass("vtkMRMLSequenceNode").GetNumberOfItems() == 0:
      self.layout.addWidget(self.recordContainer)
    self.layout.addWidget(self.fiducialContainer)

    #self.layout.addWidget(self.transformContainer)
    self.layout.addWidget(self.validationContainer)

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

    # Connections
    if slicer.mrmlScene.GetNodesByClass("vtkMRMLSequenceNode").GetNumberOfItems() == 0:
      self.connectButton.connect('clicked(bool)', self.onConnectButtonClicked)
      self.freezeButton.connect('clicked(bool)', self.onConnectButtonClicked)
      self.shortcut.connect('activated()', self.onConnectButtonClicked)
    else: 
      self.shortcut.connect('activated()', self.onFiducialClicked)
      self.freezeButton.connect('clicked(bool)', self.onFiducialClicked)
    self.RecordButton.connect('clicked(bool)', self.onRecordButtonClicked)
    self.StopRecordButton.connect('clicked(bool)', self.onStopRecordButtonClicked)
    self.SaveRecordButton.connect('clicked(bool)', self.onSaveRecordButtonClicked)
    self.copyButton.connect('clicked(bool)', self.onCopyButtonClicked)
    self.inputIPLineEdit.connect('textChanged(QString)', self.onInputChanged)
    self.inputPortLineEdit.connect('textChanged(QString)', self.onInputChanged)
    self.imageSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onImageChanged)
    self.TransformSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onTransformChanged)
    self.resetButton.connect('clicked(bool)', self.onResetButtonClicked)
    # Disable buttons until conditions are met
    self.connectButton.setEnabled(True) 
    if slicer.mrmlScene.GetNodesByClass("vtkMRMLSequenceNode").GetNumberOfItems() == 0:
      self.freezeButton.setEnabled(False) 
    self.StopRecordButton.setEnabled(False)
    
    self.sceneObserverTag = slicer.mrmlScene.AddObserver(slicer.mrmlScene.NodeAddedEvent, self.onNodeAdded)
Beispiel #9
0
    def __init__(self, parent=None, name=None, fl=0, acq_params=None,
                 path_template=None, layout='horizontal'):
        qt.QWidget.__init__(self, parent, name, fl)

        #
        # Attributes
        #
        self._beamline_setup = None
        self.previous_energy = 0

        if acq_params is None:
            self._acquisition_parameters = queue_model_objects.\
                                           AcquisitionParameters()
        else:
            self._acquisition_parameters = acq_params

        if path_template is None:
            self._path_template = queue_model_objects.PathTemplate()
        else:
            self._path_template = path_template

        self._acquisition_mib = DataModelInputBinder(self._acquisition_parameters)
        #self._path_template_mib = DataModelInputBinder(self._path_template)

        #
        # Layout
        #
        h_layout = qt.QHBoxLayout(self)

        if layout == 'vertical':
            widget = qtui.QWidgetFactory.\
                     create(os.path.join(os.path.dirname(__file__),
                                         'ui_files/acquisition_widget_vertical_layout.ui'))
        elif layout == 'horizontal':
            widget = qtui.QWidgetFactory.\
                     create(os.path.join(os.path.dirname(__file__),
                                         'ui_files/acquisition_widget_horizontal_layout.ui'))

            widget.child('inverse_beam_cbx').hide()
            widget.child('subwedge_size_label').hide()
            widget.child('subwedge_size_ledit').hide()
        else:
            widget = qtui.QWidgetFactory.\
                     create(os.path.join(os.path.dirname(__file__),
                                         'ui_files/acquisition_widget_vertical_layout.ui'))

        widget.reparent(self, qt.QPoint(0, 0))
        self.acq_widget_layout = widget
        h_layout.addWidget(self.acq_widget_layout)

        #
        # Logic
        #
        self._acquisition_mib.\
             bind_value_update('osc_start',
                               self.acq_widget_layout.child('osc_start_ledit'),
                               float,
                               qt.QDoubleValidator(-10000, 10000, 2, self))

        self._acquisition_mib.\
             bind_value_update('first_image',
                              self.acq_widget_layout.child('first_image_ledit'),
                              int,
                              qt.QIntValidator(1, 9999, self))

        self._acquisition_mib.\
             bind_value_update('exp_time',
                               self.acq_widget_layout.child('exp_time_ledit'),
                               float,
                               qt.QDoubleValidator(0.003, 6000, 3, self))

        self._acquisition_mib.\
             bind_value_update('osc_range',
                               self.acq_widget_layout.child('osc_range_ledit'),
                               float,
                               qt.QDoubleValidator(0.001, 1000, 2, self))

        self._acquisition_mib.\
             bind_value_update('num_images',
                               self.acq_widget_layout.child('num_images_ledit'),
                               int,
                               qt.QIntValidator(1, 9999, self))

        self._acquisition_mib.\
             bind_value_update('num_passes',
                               self.acq_widget_layout.child('num_passes_ledit'),
                               int,
                               qt.QIntValidator(1, 1000, self))

        self._acquisition_mib.\
             bind_value_update('overlap',
                               self.acq_widget_layout.child('overlap_ledit'),
                               float,
                               qt.QDoubleValidator(-1000, 1000, 2, self))

        self._acquisition_mib.\
             bind_value_update('energy',
                               self.acq_widget_layout.child('energy_ledit'),
                               float,
                               qt.QDoubleValidator(0, 1000, 4, self))

        self._acquisition_mib.\
             bind_value_update('transmission',
                            self.acq_widget_layout.child('transmission_ledit'),
                            float,
                            qt.QDoubleValidator(0, 1000, 2, self))

        self._acquisition_mib.\
             bind_value_update('resolution',
                               self.acq_widget_layout.child('resolution_ledit'),
                               float,
                               qt.QDoubleValidator(0, 1000, 3, self))

        self._acquisition_mib.\
             bind_value_update('inverse_beam',
                               self.acq_widget_layout.child('inverse_beam_cbx'),
                               bool,
                               None)

        self._acquisition_mib.\
             bind_value_update('shutterless',
                               self.acq_widget_layout.child('shutterless_cbx'),
                               bool,
                               None)

        qt.QObject.connect(self.acq_widget_layout.child('energies_combo'),
                        qt.SIGNAL("activated(int)"),
                        self.energy_selected)

        qt.QObject.connect(self.acq_widget_layout.child('mad_cbox'),
                        qt.SIGNAL("toggled(bool)"),
                        self.use_mad)

        qt.QObject.connect(self.acq_widget_layout.child('inverse_beam_cbx'),
                           qt.SIGNAL("toggled(bool)"),
                           self.set_use_inverse_beam)

        qt.QObject.connect(self.acq_widget_layout.child('first_image_ledit'),
                           qt.SIGNAL("textChanged(const QString &)"),
                           self.first_image_ledit_change)

        qt.QObject.connect(self.acq_widget_layout.child('num_images_ledit'),
                           qt.SIGNAL("textChanged(const QString &)"),
                           self.num_images_ledit_change)

        qt.QObject.connect(self.acq_widget_layout.child('overlap_ledit'),
                           qt.SIGNAL("textChanged(const QString &)"),
                           self.overlap_changed)

        qt.QObject.connect(self.acq_widget_layout.child('subwedge_size_ledit'),
                           qt.SIGNAL("textChanged(const QString &)"),
                           self.subwedge_size_ledit_change)

        qt.QObject.connect(self.acq_widget_layout.child('osc_start_cbox'),
                           qt.SIGNAL("toggled(bool)"),
                           self.osc_start_cbox_click)

        self.acq_widget_layout.child('subwedge_size_ledit').setDisabled(True)
        self.acq_widget_layout.child('energies_combo').setDisabled(True)
        self.acq_widget_layout.child('energies_combo').\
            insertStrList(['ip: -', 'pk: -', 'rm1: -', 'rm2: -'])

        self.acq_widget_layout.child('osc_start_ledit').setEnabled(False)
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        # Instantiate and connect widgets ...

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

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

        #
        # input volume selectors
        #
        self.inputSelectorBiPlane = slicer.qMRMLNodeComboBox()
        self.inputSelectorBiPlane.nodeTypes = [
            "vtkMRMLScalarVolumeNode", "vtkMRMLVectorVolumeNode"
        ]
        self.inputSelectorBiPlane.selectNodeUponCreation = True
        self.inputSelectorBiPlane.addEnabled = False
        self.inputSelectorBiPlane.removeEnabled = False
        self.inputSelectorBiPlane.noneEnabled = False
        self.inputSelectorBiPlane.showHidden = False
        self.inputSelectorBiPlane.showChildNodeTypes = False
        self.inputSelectorBiPlane.setMRMLScene(slicer.mrmlScene)
        self.inputSelectorBiPlane.setToolTip(
            "Pick the input to the algorithm.")
        parametersFormLayoutIO.addRow("BiPlane Volume: ",
                                      self.inputSelectorBiPlane)

        self.inputSelectorFixed = slicer.qMRMLNodeComboBox()
        self.inputSelectorFixed.nodeTypes = ["vtkMRMLScalarVolumeNode"]
        self.inputSelectorFixed.selectNodeUponCreation = True
        self.inputSelectorFixed.addEnabled = False
        self.inputSelectorFixed.removeEnabled = False
        self.inputSelectorFixed.noneEnabled = False
        self.inputSelectorFixed.showHidden = False
        self.inputSelectorFixed.showChildNodeTypes = False
        self.inputSelectorFixed.setMRMLScene(slicer.mrmlScene)
        self.inputSelectorFixed.setToolTip("Pick the input to the algorithm.")
        parametersFormLayoutIO.addRow("Fixed Volume: ",
                                      self.inputSelectorFixed)

        #
        # output volume selector
        #
        self.outputSelector = slicer.qMRMLNodeComboBox()
        self.outputSelector.nodeTypes = ["vtkMRMLVectorVolumeNode"]
        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.setMRMLScene(slicer.mrmlScene)
        self.outputSelector.setToolTip("Pick the output to the algorithm.")
        parametersFormLayoutIO.addRow("Output Volume: ", self.outputSelector)

        self.outputSelector2 = slicer.qMRMLNodeComboBox()
        self.outputSelector2.nodeTypes = ["vtkMRMLVectorVolumeNode"]
        self.outputSelector2.selectNodeUponCreation = True
        self.outputSelector2.addEnabled = True
        self.outputSelector2.removeEnabled = True
        self.outputSelector2.noneEnabled = True
        self.outputSelector2.showHidden = False
        self.outputSelector2.showChildNodeTypes = False
        self.outputSelector2.setMRMLScene(slicer.mrmlScene)
        self.outputSelector2.setToolTip("Pick the output to the algorithm.")
        parametersFormLayoutIO.addRow("Output Volume: ", self.outputSelector2)

        planeAnglesHBoxLayout = qt.QHBoxLayout()
        planeAnglesHBoxLayout.addStretch(5)

        self.onlyInt = qt.QIntValidator()
        self.onlyInt.setRange(0, 90)

        self.sagittalRotationInput = qt.QLineEdit()
        self.sagittalRotationInput.setValidator(self.onlyInt)
        self.sagittalRotationInput.setFixedWidth(60)
        planeAnglesHBoxLayout.addWidget(self.sagittalRotationInput)

        planeAnglesHBoxLayout.addStretch(1)

        self.coronalRotationInput = qt.QLineEdit()
        self.coronalRotationInput.setValidator(self.onlyInt)
        self.coronalRotationInput.setFixedWidth(60)
        planeAnglesHBoxLayout.addWidget(self.coronalRotationInput)
        planeAnglesHBoxLayout.addStretch(5)

        parametersFormLayoutIO.addRow("Plane Angles", planeAnglesHBoxLayout)

        #
        # check box to trigger taking screen shots for later use in tutorials
        #
        self.enableSliceLockFlagCheckBox = qt.QCheckBox()
        self.enableSliceLockFlagCheckBox.checked = 1
        self.enableSliceLockFlagCheckBox.setToolTip(
            "If checked, lock yellow and green slices to the 2 moving images.")
        parametersFormLayoutIO.addRow("Lock Slices to Volumes",
                                      self.enableSliceLockFlagCheckBox)

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

        ###############################################################################################################
        #
        # Auto Registration Section
        #
        ###############################################################################################################

        # TODO Some form of user guided auto registration using annulus
        parametersCollapsibleButton = ctk.ctkCollapsibleButton()
        parametersCollapsibleButton.text = "Auto Register"
        self.layout.addWidget(parametersCollapsibleButton)

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

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

        self.convertGreyscaleButton = qt.QPushButton("Convert")
        self.convertGreyscaleButton.toolTip = "Extract greyscale image."
        self.convertGreyscaleButton.enabled = True
        parametersFormLayoutReg.addRow(self.convertGreyscaleButton)
        parametersCollapsibleButton.hide()

        ###############################################################################################################
        #
        # Edit Transform Section
        #
        ###############################################################################################################

        # TODO Flip button for flipped volumes
        editCollapsibleButton = ctk.ctkCollapsibleButton()
        editCollapsibleButton.text = "Edit Transform"
        self.layout.addWidget(editCollapsibleButton)

        editFormLayout = qt.QFormLayout(editCollapsibleButton)

        self.editTransform = slicer.qMRMLNodeComboBox()
        self.editTransform.nodeTypes = ["vtkMRMLTransformNode"]
        self.editTransform.selectNodeUponCreation = True
        self.editTransform.addEnabled = False
        self.editTransform.removeEnabled = False
        self.editTransform.noneEnabled = False
        self.editTransform.showHidden = False
        self.editTransform.showChildNodeTypes = False
        self.editTransform.setMRMLScene(slicer.mrmlScene)
        self.editTransform.setToolTip("Pick the output to the algorithm.")
        editFormLayout.addRow("Transform: ", self.editTransform)

        self.translationSliders = slicer.qMRMLTransformSliders()
        self.translationSliders.SingleStep = 0.5
        editFormLayout.addRow(self.translationSliders)

        self.rotationSliders = slicer.qMRMLTransformSliders()
        self.rotationSliders.TypeOfTransform = self.rotationSliders.ROTATION
        self.rotationSliders.Title = "Rotation"
        self.rotationSliders.SingleStep = 0.5
        editFormLayout.addRow(self.rotationSliders)

        # connections
        self.initTransformButton.connect('clicked(bool)',
                                         self.onInitTransformButton)
        self.inputSelectorFixed.connect("currentNodeChanged(vtkMRMLNode*)",
                                        self.onSelect)
        self.inputSelectorBiPlane.connect("currentNodeChanged(vtkMRMLNode*)",
                                          self.onSelect)
        self.outputSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                    self.onSelect)
        self.outputSelector2.connect("currentNodeChanged(vtkMRMLNode*)",
                                     self.onSelect)
        self.sagittalRotationInput.connect("textEdited(QString)",
                                           self.onSelect)
        self.coronalRotationInput.connect("textEdited(QString)", self.onSelect)
        self.enableSliceLockFlagCheckBox.connect(
            "stateChanged(int)", self.onEnableSliceLockFlagChanged)

        self.editTransform.connect("currentNodeChanged(vtkMRMLNode*)",
                                   self.onTransformSelect)

        self.convertGreyscaleButton.connect(
            'clicked(bool)', self.onConvertGreyscaleButtonClicked)

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

        # Refresh Apply button state
        self.onSelect()
Beispiel #11
0
    def __init__(self, parent=None, name="", fl=0, data_model=None, layout=None):
        qt.QWidget.__init__(self, parent, name, fl)

        #
        # Attributes
        #
        self._base_image_dir = None
        self._base_process_dir = None
        self.path_conflict_state = False

        if data_model is None:
            self._data_model = queue_model_objects.PathTemplate()
        else:
            self._data_model = data_model

        self._data_model_pm = DataModelInputBinder(self._data_model)

        #
        # Layout
        #
        h_layout = qt.QHBoxLayout(self)

        if layout == "vertical":
            widget = qtui.QWidgetFactory.create(
                os.path.join(
                    os.path.dirname(__file__),
                    "ui_files/data_path_widget_vertical_layout.ui",
                )
            )
        elif layout == "horizontal":
            widget = qtui.QWidgetFactory.create(
                os.path.join(
                    os.path.dirname(__file__),
                    "ui_files/data_path_widget_horizontal_layout.ui",
                )
            )
        else:
            widget = qtui.QWidgetFactory.create(
                os.path.join(
                    os.path.dirname(__file__),
                    "ui_files/data_path_widget_horizontal_layout.ui",
                )
            )

        self.data_path_widget_layout = widget
        widget.reparent(self, qt.QPoint(0, 0))
        h_layout.addWidget(self.data_path_widget_layout)

        #
        # Logic
        #
        self._data_model_pm.bind_value_update(
            "base_prefix", self.data_path_widget_layout.child("prefix_ledit"), str, None
        )

        self._data_model_pm.bind_value_update(
            "run_number",
            self.data_path_widget_layout.child("run_number_ledit"),
            int,
            qt.QIntValidator(0, 1000, self),
        )

        qt.QObject.connect(
            self.data_path_widget_layout.child("prefix_ledit"),
            qt.SIGNAL("textChanged(const QString &)"),
            self._prefix_ledit_change,
        )

        qt.QObject.connect(
            self.data_path_widget_layout.child("run_number_ledit"),
            qt.SIGNAL("textChanged(const QString &)"),
            self._run_number_ledit_change,
        )

        qt.QObject.connect(
            self.data_path_widget_layout.child("browse_button"),
            qt.SIGNAL("clicked()"),
            self._browse_clicked,
        )

        qt.QObject.connect(
            self.data_path_widget_layout.child("folder_ledit"),
            qt.SIGNAL("textChanged(const QString &)"),
            self._folder_ledit_change,
        )
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        # Instantiate and connect widgets ...

        # define lists to store images and transforms
        self.imageNodes = []
        self.transformNodes = []
        self.roiNodes = []
        self.layouts = []
        self.filename = None

        #
        # number of images
        #
        numberOfImagesButton = slicer.qMRMLCollapsibleButton()
        numberOfImagesButton.text = "Setup"
        self.layout.addWidget(numberOfImagesButton)

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

        #
        # Number of images selector (not fully implemented!!!)
        #
        self.numberSelector = qt.QLineEdit()
        self.numberSelector.setValidator(qt.QIntValidator())
        self.numberSelector.setMaxLength(2)
        self.numberSelector.toolTip = "Enter in the number of images for comparison."
        parametersFormLayout.addRow("Number of images: ", self.numberSelector)
        self.numberSelector.textChanged.connect(self.numberchanged)

        #
        # Resample rois Button
        #
        self.fileDialogButton = qt.QPushButton("Select file to store data.")
        self.fileDialogButton.toolTip = "Select the csv file to store the final feature results."
        self.fileDialogButton.enabled = True
        parametersFormLayout.addRow("CSV file: ", self.fileDialogButton)

        # connections
        self.fileDialogButton.connect('clicked(bool)', self.onFileDialog)

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

        #
        # actions Area
        #
        actionsCollapsibleButton = slicer.qMRMLCollapsibleButton()
        actionsCollapsibleButton.text = "Actions"
        self.layout.addWidget(actionsCollapsibleButton)

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

        #
        # Resample rois Button
        #
        self.resampleLabelMapsButton = qt.QPushButton(
            "Resample region of interest")
        self.resampleLabelMapsButton.toolTip = "Resample the label maps to find the roi in all images in their original image space."
        self.resampleLabelMapsButton.enabled = True
        parametersFormLayout.addRow(self.resampleLabelMapsButton)

        # connections
        self.resampleLabelMapsButton.connect('clicked(bool)',
                                             self.onresampleLabelMapsButton)

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

        # Refresh Apply button state
        self.onSelectResample()

        #
        # Calculate statistics Button
        #
        self.calculateStatsButton = qt.QPushButton("Calculate statistics")
        self.calculateStatsButton.toolTip = "Calculate statistics from each region of interest."
        self.calculateStatsButton.enabled = True
        parametersFormLayout.addRow(self.calculateStatsButton)

        # connections
        self.calculateStatsButton.connect('clicked(bool)',
                                          self.oncalculateStatsButton)

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

        # Refresh Apply button state
        self.onSelectCalculate()

        #
        # Resample into baseline space
        #
        self.baselineSpaceButton = qt.QPushButton("Baseline space")
        self.baselineSpaceButton.toolTip = "Resample rois into baseline image space."
        self.baselineSpaceButton.enabled = True
        parametersFormLayout.addRow(self.baselineSpaceButton)

        # connections
        self.baselineSpaceButton.connect('clicked(bool)',
                                         self.onbaselineSpaceButton)

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

        # Refresh Apply button state
        self.onBaselineSpace()

        #
        # Find extent button
        #
        self.findExtentButton = qt.QPushButton("Find extent")
        self.findExtentButton.toolTip = "Find extent of the label mask."
        self.findExtentButton.enabled = True
        parametersFormLayout.addRow(self.findExtentButton)

        # connections
        self.findExtentButton.connect('clicked(bool)', self.onfindExtentButton)

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

        # Refresh Apply button state
        self.onFindExtent()

        #
        # Show layout Button
        #
        self.showLayoutButton = qt.QPushButton("Registered images layout")
        self.showLayoutButton.toolTip = "View the images in the baseline image space with transforms applied."
        self.showLayoutButton.enabled = True
        parametersFormLayout.addRow(self.showLayoutButton)

        # connections
        self.showLayoutButton.connect('clicked(bool)', self.onshowLayoutButton)

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

        # Refresh Apply button state
        self.onShowLayout()

        #
        # baseline image Area
        #
        baselineCollapsibleButton = slicer.qMRMLCollapsibleButton()
        baselineCollapsibleButton.text = "Baseline image"
        self.layout.addWidget(baselineCollapsibleButton)

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

        #
        # image (original) volume selector
        #
        self.baselineSelector = slicer.qMRMLNodeComboBox()
        self.baselineSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"]
        self.baselineSelector.selectNodeUponCreation = True
        self.baselineSelector.addEnabled = False
        self.baselineSelector.removeEnabled = False
        self.baselineSelector.noneEnabled = False
        self.baselineSelector.showHidden = False
        self.baselineSelector.showChildNodeTypes = False
        self.baselineSelector.setMRMLScene(slicer.mrmlScene)
        self.baselineSelector.setToolTip(
            "Pick the image with the original ROI.")
        parametersFormLayout.addRow("Baseline image: ", self.baselineSelector)

        #
        # ROI volume selector
        #
        self.baselineRoiSelector = slicer.qMRMLNodeComboBox()
        self.baselineRoiSelector.nodeTypes = ["vtkMRMLLabelMapVolumeNode"]
        self.baselineRoiSelector.selectNodeUponCreation = True
        self.baselineRoiSelector.addEnabled = False
        self.baselineRoiSelector.removeEnabled = False
        self.baselineRoiSelector.noneEnabled = False
        self.baselineRoiSelector.showHidden = False
        self.baselineRoiSelector.showChildNodeTypes = False
        self.baselineRoiSelector.setMRMLScene(slicer.mrmlScene)
        self.baselineRoiSelector.setToolTip("Pick the region of interest.")
        parametersFormLayout.addRow("Region of interest (label map) ",
                                    self.baselineRoiSelector)
Beispiel #13
0
  def setup(self):
    # this is the function that implements all GUI 
    ScriptedLoadableModuleWidget.setup(self)
    # This sets the view being used to the red view only 
    slicer.app.layoutManager().setLayout(slicer.vtkMRMLLayoutNode.SlicerLayoutOneUpRedSliceView)
    #This code block creates a collapsible button 
    #This defines which type of button you are using 
    self.usContainer = ctk.ctkCollapsibleButton()
    #This is what the button will say 
    self.usContainer.text = "Ultrasound Information"
    #Thiss actually creates that button
    self.layout.addWidget(self.usContainer)
    #This creates a variable that describes layout within this collapsible button 
    self.usLayout = qt.QFormLayout(self.usContainer)

    #This descirbes the type of widget 
    self.inputIPLineEdit = qt.QLineEdit()
    #This sets a placehoder example of what should be inputted to the line edit 
    self.inputIPLineEdit.setPlaceholderText("127.0.0.1")
    #This is the help tooltip 
    self.inputIPLineEdit.toolTip = "Put the IP address of your ultrasound device here"
    #This is the text that is input inot the line 
    self.IPLabel = qt.QLabel("Server IP:")
    if slicer.mrmlScene.GetNodesByClass("vtkMRMLSequenceNode").GetNumberOfItems() == 0:
      self.usLayout.addRow(self.IPLabel, self.inputIPLineEdit)
    #This code block is the exact same as the one above only it asks for the server port 
    self.layout.addWidget(self.usContainer)
    self.inputPortLineEdit = qt.QLineEdit()
    self.inputPortLineEdit.setPlaceholderText("18944")
    self.inputPortLineEdit.setValidator(qt.QIntValidator())
    self.inputPortLineEdit.toolTip = "Put the Port of your ultrasound device here"
    self.portLabel = qt.QLabel("Sever Port:")
    if slicer.mrmlScene.GetNodesByClass("vtkMRMLSequenceNode").GetNumberOfItems() == 0:
      self.usLayout.addRow(self.portLabel, self.inputPortLineEdit)
    #This is a push button 
    self.connectButton = qt.QPushButton()
    self.connectButton.setDefault(False)
    #This button says connect 
    self.connectButton.text = "Connect"
    #help tooltip that explains the funciton 
    self.connectButton.toolTip = "Connects to Ultrasound"
    #adds the widget to the layout 
    if slicer.mrmlScene.GetNodesByClass("vtkMRMLSequenceNode").GetNumberOfItems() == 0:
      self.usLayout.addWidget(self.connectButton)
    # Combobox for image selection
    self.imageSelector = slicer.qMRMLNodeComboBox()
    self.imageSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"]
    self.imageSelector.selectNodeUponCreation = True
    self.imageSelector.addEnabled = False
    self.imageSelector.removeEnabled = False
    self.imageSelector.noneEnabled = True
    self.imageSelector.showHidden = False
    self.imageSelector.showChildNodeTypes = False
    self.imageSelector.setMRMLScene( slicer.mrmlScene )
    self.imageSelector.setToolTip( "Pick the image to be used." )
    self.usLayout.addRow("US Volume: ", self.imageSelector)
    
    #add combo box for linear transform node 
    self.TransformSelector = slicer.qMRMLNodeComboBox()
    self.TransformSelector.nodeTypes = ["vtkMRMLLinearTransformNode"]
    self.TransformSelector.selectNodeUponCreation = True
    self.TransformSelector.addEnabled = False
    self.TransformSelector.removeEnabled = False
    self.TransformSelector.noneEnabled = True
    self.TransformSelector.showHidden = False
    self.TransformSelector.showChildNodeTypes = False
    self.TransformSelector.setMRMLScene( slicer.mrmlScene )
    self.TransformSelector.setToolTip( "Pick the transform representing the straw line." )
    self.usLayout.addRow("Tip to Probe: ", self.TransformSelector)
    
    self.calibrationContainer = ctk.ctkCollapsibleButton()
    #This is what the button will say 
    self.calibrationContainer.text = "Calibration Parameters"
    #Thiss actually creates that button
    self.layout.addWidget(self.calibrationContainer)
    #This creates a variable that describes layout within this collapsible button 
    self.calibrationLayout = qt.QFormLayout(self.calibrationContainer)
    
    self.segLabel = qt.QLabel()
    self.calibrationLayout.addRow(qt.QLabel("Type of segmentation:"), self.segLabel)
    
    self.manual = qt.QCheckBox()
    self.manual.text = "Check for manual segmentation"
    self.calibrationLayout.addWidget(self.manual)
    
    self.auto = qt.QCheckBox()
    self.auto.text = "Check for automatic segmentation for ultrasonix L14-5 38"
    self.calibrationLayout.addWidget(self.auto)
    
    self.recordContainer = ctk.ctkCollapsibleButton()
    #This is what the button will say 
    self.recordContainer.text = "Recording Options"
    #Thiss actually creates that button
    #This creates a variable that describes layout within this collapsible button 
    self.recordLayout = qt.QFormLayout(self.recordContainer)
    
    self.RecordButton = qt.QPushButton() 
    self.RecordButton.text = "Start Recording" 
    self.recordLayout.addWidget(self.RecordButton)
    
    self.StopRecordButton = qt.QPushButton() 
    self.StopRecordButton.text = "Stop Recording" 
    self.recordLayout.addWidget(self.StopRecordButton)
    
    self.pathInput = qt.QLineEdit()
    self.pathInput.setPlaceholderText("Enter the path to save files to")
    self.pathText = qt.QLabel("File Path:")
    self.recordLayout.addRow(self.pathText, self.pathInput)
    
    self.SaveRecordButton = qt.QPushButton() 
    self.SaveRecordButton.text = "Save Recording" 
    self.recordLayout.addWidget(self.SaveRecordButton)
    
    # This creates another collapsible button
    self.fiducialContainer = ctk.ctkCollapsibleButton()
    self.fiducialContainer.text = "Registration"

    self.fiducialLayout = qt.QFormLayout(self.fiducialContainer)

    #This is the exact same as the code block below but it freezes the US to capture a screenshot 
    self.freezeButton = qt.QPushButton()
    if slicer.mrmlScene.GetNodesByClass("vtkMRMLSequenceNode").GetNumberOfItems() == 0:
      self.freezeButton.text = "Place Fiducial ('f')"
    else:
      self.freezeButton.text = "Place Fiducial"
    self.freezeButton.toolTip = "Freeze the ultrasound image for fiducial placement"
    self.fiducialLayout.addRow(self.freezeButton)
    self.shortcut = qt.QShortcut(qt.QKeySequence('f'), slicer.util.mainWindow())
    self.undoButton = qt.QPushButton()
    self.undoButton.setText("Undo ('u')")
    self.fiducialLayout.addRow(self.undoButton)
    self.uShortcut = qt.QShortcut(qt.QKeySequence('ctrl+u'), slicer.util.mainWindow())
    self.redoButton = qt.QPushButton()
    self.rShortcut = qt.QShortcut(qt.QKeySequence('r'), slicer.util.mainWindow())
    self.redoButton.setText("Redo ('r')")
    self.fiducialLayout.addRow(self.redoButton)
    
    self.numFidLabel = qt.QLabel()
    self.fiducialLayout.addRow(qt.QLabel("Fiducials collected:"), self.numFidLabel)
    
    self.transformTable = ctk.ctkMatrixWidget() 
    self.transformTable.columnCount = 4
    self.transformTable.rowCount = 4 
    self.transformTable.setDecimals(3)
    for i in range (0,4): 
      for j in range(0,4): 
        self.transformTable.setValue(i,j, (self.imageToProbe.GetElement(i,j)))
    
    self.fiducialLayout.addRow(qt.QLabel("Image to probe transform:"))
    self.fiducialLayout.addRow(self.transformTable)
         # Add vertical spacer
    
    self.copyButton = qt.QPushButton()
    self.copyButton.setText('Copy Transform')
    self.copyButton.toolTip = "Copy" 
    self.fiducialLayout.addRow(self.copyButton) 
    
    self.validationContainer = ctk.ctkCollapsibleButton()
    self.validationContainer.text = "Validation"
    self.validationLayout = qt.QFormLayout(self.validationContainer)

    self.visualizeButton = qt.QPushButton('Show 3D Scene')
    self.visualizeButton.toolTip = "This button enables the 3D view for visual validation"
    self.validationLayout.addRow(self.visualizeButton)
    self.visualizeButton.connect('clicked(bool)', self.onVisualizeButtonClicked)
    self.resetButton = qt.QPushButton('Reset')
    self.resetButton.setDefault(False)
    self.resetButton.toolTip = "This Button Resets the Module"
    self.validationLayout.addRow(self.resetButton)

    # Add the containers to the parent
    self.layout.addWidget(self.usContainer)
    self.layout.addWidget(self.calibrationContainer)
    if slicer.mrmlScene.GetNodesByClass("vtkMRMLSequenceNode").GetNumberOfItems() == 0:
      self.layout.addWidget(self.recordContainer)
    self.layout.addWidget(self.fiducialContainer)

    #self.layout.addWidget(self.transformContainer)
    self.layout.addWidget(self.validationContainer)

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

    # Connections
    if slicer.mrmlScene.GetNodesByClass("vtkMRMLSequenceNode").GetNumberOfItems() == 0:
      self.connectButton.connect('clicked(bool)', self.onConnectButtonClicked)
      self.freezeButton.connect('clicked(bool)', self.onConnectButtonClicked)
      self.shortcut.connect('activated()', self.onConnectButtonClicked)
    else: 
      self.shortcut.connect('activated()', self.onFiducialClicked)
      self.freezeButton.connect('clicked(bool)', self.onFiducialClicked)
    self.RecordButton.connect('clicked(bool)', self.onRecordButtonClicked)
    self.StopRecordButton.connect('clicked(bool)', self.onStopRecordButtonClicked)
    self.SaveRecordButton.connect('clicked(bool)', self.onSaveRecordButtonClicked)
    self.copyButton.connect('clicked(bool)', self.onCopyButtonClicked)
    self.inputIPLineEdit.connect('textChanged(QString)', self.onInputChanged)
    self.inputPortLineEdit.connect('textChanged(QString)', self.onInputChanged)
    self.imageSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onImageChanged)
    self.TransformSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onTransformChanged)
    self.resetButton.connect('clicked(bool)', self.onResetButtonClicked)
    self.undoButton.connect('clicked(bool)', self.onUndoButtonClicked)
    self.uShortcut.connect('activated()', self.onUndoButtonClicked)
    self.redoButton.connect('clicked(bool)', self.onRedoButtonClicked)
    self.rShortcut.connect('activated()', self.onRedoButtonClicked)
    # Disable buttons until conditions are met
    self.connectButton.setEnabled(True) 
    # if slicer.mrmlScene.GetNodesByClass("vtkMRMLSequenceNode").GetNumberOfItems() == 0:
      # self.freezeButton.setEnabled(False) 
    self.StopRecordButton.setEnabled(False)
    
    self.sceneObserverTag = slicer.mrmlScene.AddObserver(slicer.mrmlScene.NodeAddedEvent, self.onNodeAdded)
Beispiel #14
0
    def setup(self):
        # this is the function that implements all GUI
        ScriptedLoadableModuleWidget.setup(self)

        slicer.mymod = self
        #This sets the view being used to the red view only
        slicer.app.layoutManager().setLayout(
            slicer.vtkMRMLLayoutNode.SlicerLayoutOneUpRedSliceView)
        l = slicer.modules.createmodels.logic()
        self.needle = l.CreateNeedle(180, 0.3, 0, False)

        #This code block creates a collapsible button
        #This defines which type of button you are using
        self.usButton = ctk.ctkCollapsibleButton()
        #This is what the button will say
        self.usButton.text = "Ultrasound Information"
        #Thiss actually creates that button
        self.layout.addWidget(self.usButton)
        #This creates a variable that describes layout within this collapsible button
        self.usLayout = qt.QFormLayout(self.usButton)

        #This descirbes the type of widget
        self.inputIPLineEdit = qt.QLineEdit()
        #This sets a placehoder example of what should be inputted to the line edit
        self.inputIPLineEdit.setPlaceholderText("127.0.0.1")
        #This is the help tooltip
        self.inputIPLineEdit.toolTip = "Put the IP address of your ultrasound device here"
        #This is the text that is input inot the line
        self.usLayout.addRow("Server IP:", self.inputIPLineEdit)

        #This code block is the exact same as the one above only it asks for the server port
        self.layout.addWidget(self.usButton)
        self.inputPortLineEdit = qt.QLineEdit()
        self.inputPortLineEdit.setPlaceholderText("18944")
        self.inputPortLineEdit.setValidator(qt.QIntValidator())
        self.inputPortLineEdit.toolTip = "Put the Port of your ultrasound device here"
        self.usLayout.addRow("Server Port:", self.inputPortLineEdit)

        #This is a push button
        self.connectButton = qt.QPushButton()
        #This button says connect
        self.connectButton.text = "Connect"
        #help tooltip that explains the funciton
        self.connectButton.toolTip = "Connects to Ultrasound"
        #adds the widget to the layout
        self.usLayout.addWidget(self.connectButton)

        # Combobox for image selection
        self.imageSelector = slicer.qMRMLNodeComboBox()
        self.imageSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"]
        self.imageSelector.selectNodeUponCreation = True
        self.imageSelector.addEnabled = False
        self.imageSelector.removeEnabled = False
        self.imageSelector.noneEnabled = True
        self.imageSelector.showHidden = False
        self.imageSelector.showChildNodeTypes = False
        self.imageSelector.setMRMLScene(slicer.mrmlScene)
        self.imageSelector.setToolTip("Pick the image to be used.")
        self.usLayout.addRow("US Volume: ", self.imageSelector)

        self.guidedButton = qt.QCheckBox()
        self.guidedButton.text = "Select to turn guidance off"
        self.guidedButton.toolTip = "This allows the user to select if they want to use the guidance"
        self.usLayout.addRow(self.guidedButton)

        # This creates another collapsible button
        self.fiducialContainer = ctk.ctkCollapsibleButton()
        self.fiducialContainer.text = "Registration"
        self.fiducialLayout = qt.QFormLayout(self.fiducialContainer)

        #add combo box for linear transform node
        self.TransformSelector = slicer.qMRMLNodeComboBox()
        self.TransformSelector.nodeTypes = ["vtkMRMLLinearTransformNode"]
        self.TransformSelector.selectNodeUponCreation = True
        self.TransformSelector.addEnabled = False
        self.TransformSelector.removeEnabled = False
        self.TransformSelector.noneEnabled = True
        self.TransformSelector.showHidden = False
        self.TransformSelector.showChildNodeTypes = False
        self.TransformSelector.setMRMLScene(slicer.mrmlScene)
        self.TransformSelector.setToolTip(
            "Pick the transform representing the straw line.")
        self.fiducialLayout.addRow("Tip to Probe: ", self.TransformSelector)

        # self.probeTransformSelector = slicer.qMRMLNodeComboBox()
        # self.probeTransformSelector.nodeTypes = ["vtkMRMLLinearTransformNode"]
        # self.probeTransformSelector.selectNodeUponCreation = True
        # self.probeTransformSelector.addEnabled = False
        # self.probeTransformSelector.removeEnabled = False
        # self.probeTransformSelector.noneEnabled = True
        # self.probeTransformSelector.showHidden = False
        # self.probeTransformSelector.showChildNodeTypes = False
        # self.probeTransformSelector.setMRMLScene( slicer.mrmlScene )
        # self.probeTransformSelector.setToolTip( "Pick the transform representing the probe line." )
        # self.fiducialLayout.addRow("Probe transform: ", self.probeTransformSelector)

        #This is the exact same as the code block below but it freezes the US to capture a screenshot
        self.freezeButton = qt.QPushButton()
        self.freezeButton.text = "Freeze"
        self.freezeButton.toolTip = "Freeze the ultrasound image for fiducial placement"
        self.fiducialLayout.addRow(self.freezeButton)

        # This is another push button
        # self.fiducialButton = qt.QPushButton("Place Fiducial")
        # self.fiducialButton.toolTip = "Creates a fiducial to be placed on the straw"
        # self.fiducialLayout.addRow(self.fiducialButton)
        # #When clicked it runs the function onFaducialButtonClicked
        # self.fiducialButton.connect('clicked(bool)', self.onFiducialButtonClicked)

        self.numFidLabel = qt.QLabel()
        self.fiducialLayout.addRow(qt.QLabel("Fiducials collected:"),
                                   self.numFidLabel)

        self.validationContainer = ctk.ctkCollapsibleButton()
        self.validationContainer.text = "Validation"
        self.validationLayout = qt.QFormLayout(self.validationContainer)

        self.visualizeButton = qt.QPushButton('Show 3D Scene')
        self.visualizeButton.toolTip = "This button enables the 3D view for visual validation"
        self.validationLayout.addRow(self.visualizeButton)
        self.visualizeButton.connect('clicked(bool)',
                                     self.onVisualizeButtonClicked)

        self.resetButton = qt.QPushButton('Reset')
        self.resetButton.toolTip = "This Button Resets the Module"
        self.validationLayout.addRow(self.resetButton)

        # Add the containers to the parent
        self.layout.addWidget(self.usButton)
        self.layout.addWidget(self.fiducialContainer)
        self.layout.addWidget(self.validationContainer)

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

        # Connections
        self.connectButton.connect('clicked(bool)',
                                   self.onConnectButtonClicked)
        self.freezeButton.connect('clicked(bool)', self.onConnectButtonClicked)
        self.inputIPLineEdit.connect('textChanged(QString)',
                                     self.onInputChanged)
        self.inputPortLineEdit.connect('textChanged(QString)',
                                       self.onInputChanged)
        self.guidedButton.connect('stateChanged(int)',
                                  self.onGuidedButtonClicked)
        self.imageSelector.connect('currentNodeChanged(vtkMRMLNode*)',
                                   self.onImageChanged)
        self.resetButton.connect('clicked(bool)', self.onResetButtonClicked)

        # Disable buttons until conditions are met
        self.connectButton.setEnabled(False)
        self.freezeButton.setEnabled(False)

        #This adds an observer to scene to listen for mrml node
        self.sceneObserverTag = slicer.mrmlScene.AddObserver(
            slicer.mrmlScene.NodeAddedEvent, self.onNodeAdded)

        layoutLogic = slicer.app.layoutManager().layoutLogic()
        customLayout = (
            "<layout type=\"horizontal\" split=\"false\" >"
            " <item>"
            "  <view class=\"vtkMRMLSliceNode\" singletontag=\"Red\">"
            "   <property name=\"orientation\" action=\"default\">Reformat</property>"
            "   <property name=\"viewlabel\" action=\"default\">R</property>"
            "   <property name=\"viewcolor\" action=\"default\">#F34A33</property>"
            "  </view>"
            " </item>"
            " <item>"
            "  <view class=\"vtkMRMLViewNode\" singletontag=\"1\">"
            "   <property name=\"viewlabel\" action=\"default\">1</property>"
            "  </view>"
            " </item>"
            "</layout>")
        layoutLogic.GetLayoutNode().AddLayoutDescription(
            self.customLayoutId, customLayout)

        self.outputRegistrationTransformNode = slicer.vtkMRMLLinearTransformNode(
        )
        slicer.mrmlScene.AddNode(self.outputRegistrationTransformNode)
        self.outputRegistrationTransformNode.SetName('ImageToProbe')

        self.NeedleTipToReferenceTransformNode = slicer.vtkMRMLLinearTransformNode(
        )
        slicer.mrmlScene.AddNode(self.NeedleTipToReferenceTransformNode)