예제 #1
0
def browse_folders(event):
    tb = XRCCTRL(panel, 'path')
    dlg = wx.DirDialog(panel)
    if tb.GetValue():
        dlg.SetPath(tb.GetValue())
    if dlg.ShowModal() == wx.ID_OK:
        tb.SetValue(dlg.GetPath())
예제 #2
0
class ScaleDoseDialog(wx.Dialog):
    """Dialog that shows the options to scale the DICOM RT dose data."""
    def __init__(self):
        pre = wx.PreDialog()
        # the Create step is done by XRC.
        self.PostCreate(pre)

    def Init(self, rxdose):
        """Method called after the dialog has been initialized."""

        # Set window icon
        if not guiutil.IsMac():
            self.SetIcon(guiutil.get_icon())

        # Initialize controls
        self.txtOriginalRxDose = XRCCTRL(self, 'txtOriginalRxDose')
        self.txtNewRxDose = XRCCTRL(self, 'txtNewRxDose')

        # Bind interface events to the proper methods
        wx.EVT_BUTTON(self, wx.ID_OK, self.OnOK)

        # Pre-select the text on the text controls due to a Mac OS X bug
        self.txtOriginalRxDose.SetSelection(-1, -1)
        self.txtNewRxDose.SetSelection(-1, -1)

        # Initialize variables
        self.txtOriginalRxDose.SetValue(str(int(rxdose)))
        self.txtNewRxDose.SetValue(str(int(rxdose) / 2))

    def OnOK(self, evt):
        """Return the options from the anonymize data dialog."""

        self.oldRxDose = int(self.txtOriginalRxDose.GetValue())
        self.newRxDose = int(self.txtNewRxDose.GetValue())

        self.EndModal(wx.ID_OK)
예제 #3
0
class DoseDialog(wx.Dialog):
    def __init__(self):
        pre = wx.PreDialog()
        self.PostCreate(pre)

    def Init(self, dosecube):
        self.dosecube = dosecube
        self.txt_targetdose = XRCCTRL(self, "txt_targetdose")
        self.txt_targetdose.SetValue("%.1f" % self.dosecube.get_dose())

        self.btn_ok = XRCCTRL(self, 'btn_ok')
        wx.EVT_BUTTON(self, XRCID('btn_ok'), self.save_and_close)

        self.btn_cancel = XRCCTRL(self, 'btn_close')
        wx.EVT_BUTTON(self, XRCID('btn_close'), self.close)

    def save_and_close(self, evt):
        self.dosecube.set_dose(self.txt_targetdose.GetValue())
        self.Close()

    def close(self, evt):
        self.Close()
예제 #4
0
class AnonymizeDialog(wx.Dialog):
    """Dialog that shows the options to anonymize DICOM / DICOM RT data."""
    def __init__(self):
        pre = wx.PreDialog()
        # the Create step is done by XRC.
        self.PostCreate(pre)

    def Init(self):
        """Method called after the dialog has been initialized."""

        # Set window icon
        if not guiutil.IsMac():
            self.SetIcon(guiutil.get_icon())

        # Initialize controls
        self.txtDICOMFolder = XRCCTRL(self, 'txtDICOMFolder')
        self.checkPatientName = XRCCTRL(self, 'checkPatientName')
        self.txtFirstName = XRCCTRL(self, 'txtFirstName')
        self.txtLastName = XRCCTRL(self, 'txtLastName')
        self.checkPatientID = XRCCTRL(self, 'checkPatientID')
        self.txtPatientID = XRCCTRL(self, 'txtPatientID')
        self.checkPrivateTags = XRCCTRL(self, 'checkPrivateTags')
        self.bmpError = XRCCTRL(self, 'bmpError')
        self.lblDescription = XRCCTRL(self, 'lblDescription')

        # Bind interface events to the proper methods
        wx.EVT_BUTTON(self, XRCID('btnFolderBrowse'), self.OnFolderBrowse)
        wx.EVT_CHECKBOX(self, XRCID('checkPatientName'),
                        self.OnCheckPatientName)
        wx.EVT_CHECKBOX(self, XRCID('checkPatientID'), self.OnCheckPatientID)
        wx.EVT_BUTTON(self, wx.ID_OK, self.OnOK)

        # Set and bold the font of the description label
        if guiutil.IsMac():
            font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
            font.SetWeight(wx.FONTWEIGHT_BOLD)
            self.lblDescription.SetFont(font)

        # Initialize the import location via pubsub
        pub.subscribe(self.OnImportPrefsChange,
                      'general.dicom.import_location')
        pub.sendMessage('preferences.requested.value',
                        'general.dicom.import_location')

        # Pre-select the text on the text controls due to a Mac OS X bug
        self.txtFirstName.SetSelection(-1, -1)
        self.txtLastName.SetSelection(-1, -1)
        self.txtPatientID.SetSelection(-1, -1)

        # Load the error bitmap
        self.bmpError.SetBitmap(wx.Bitmap(util.GetResourcePath('error.png')))

        # Initialize variables
        self.name = self.txtLastName.GetValue(
        ) + '^' + self.txtFirstName.GetValue()
        self.patientid = self.txtPatientID.GetValue()
        self.privatetags = True

    def OnImportPrefsChange(self, msg):
        """When the import preferences change, update the values."""

        self.path = unicode(msg.data)
        self.txtDICOMFolder.SetValue(self.path)

    def OnFolderBrowse(self, evt):
        """Get the directory selected by the user."""

        dlg = wx.DirDialog(
            self,
            defaultPath=self.path,
            message="Choose a folder to save the anonymized DICOM data...")

        if dlg.ShowModal() == wx.ID_OK:
            self.path = dlg.GetPath()
            self.txtDICOMFolder.SetValue(self.path)

        dlg.Destroy()

    def OnCheckPatientName(self, evt):
        """Enable or disable whether the patient's name is anonymized."""

        self.txtFirstName.Enable(evt.IsChecked())
        self.txtLastName.Enable(evt.IsChecked())
        if not evt.IsChecked():
            self.txtDICOMFolder.SetFocus()
        else:
            self.txtFirstName.SetFocus()
            self.txtFirstName.SetSelection(-1, -1)

    def OnCheckPatientID(self, evt):
        """Enable or disable whether the patient's ID is anonymized."""

        self.txtPatientID.Enable(evt.IsChecked())
        if not evt.IsChecked():
            self.txtDICOMFolder.SetFocus()
        else:
            self.txtPatientID.SetFocus()
            self.txtPatientID.SetSelection(-1, -1)

    def OnOK(self, evt):
        """Return the options from the anonymize data dialog."""

        # Patient name
        if self.checkPatientName.IsChecked():
            self.name = self.txtLastName.GetValue()
            if len(self.txtFirstName.GetValue()):
                self.name = self.name + '^' + self.txtFirstName.GetValue()
        else:
            self.name = ''

        # Patient ID
        if self.checkPatientID.IsChecked():
            self.patientid = self.txtPatientID.GetValue()
        else:
            self.patientid = ''

        # Private tags
        if self.checkPrivateTags.IsChecked():
            self.privatetags = True
        else:
            self.privatetags = False

        self.EndModal(wx.ID_OK)

    def OnDestroy(self, evt):
        """Unbind to all events before the plugin is destroyed."""
        pub.unsubscribe(self.OnImportPrefsChange,
                        'general.dicom.import_location')
        pub.unsubscribe(self.OnUpdatePatient, 'patient.updated.raw_data')
예제 #5
0
class TripExportDialog(wx.Dialog):
    def __init__(self):
        pre = wx.PreDialog()
        self.PostCreate(pre)

    def Init(self, plan):
        self.output_path = ''
        self.drop_type = XRCCTRL(self, "drop_type")
        self.txt_prefix = XRCCTRL(self, "txt_prefix")
        self.txt_prefix.SetValue(plan.get_name())

        self.label_folder = XRCCTRL(self, "label_folder")

        wx.EVT_BUTTON(self, XRCID("btn_cancel"), self.close)
        wx.EVT_BUTTON(self, XRCID("btn_browse"), self.browse_folder)
        wx.EVT_BUTTON(self, XRCID("btn_generate"), self.generate)
        self.plan = plan

        pub.subscribe(self.on_patient_updated, "patient.loaded")
        pub.subscribe(self.on_export_voxelplan_changed,
                      "general.export.voxelplan")
        pub.sendMessage("settings.value.request", "general.export.voxelplan")
        pub.sendMessage("patient.request", None)

    def on_export_voxelplan_changed(self, msg):
        if not msg.data is None:
            self.output_path = msg.data
            self.label_folder.SetLabel(self.output_path)

    def on_patient_updated(self, msg):
        self.data = msg.data

    def browse_folder(self, evt):
        dlg = wx.DirDialog(self,
                           defaultPath=self.output_path,
                           message="Choose where the plan should be placed")
        if dlg.ShowModal() == wx.ID_OK:
            path = dlg.GetPath()
            self.output_path = path
            pub.sendMessage("settings.value.updated",
                            {"general.export.voxelplan": path})
            self.label_folder.SetLabel(path)

    def generate(self, evt):
        idx = self.drop_type.GetSelection()
        file_prefix = self.txt_prefix.GetValue()
        if len(file_prefix) == 0:
            raise InputError("File Prefix should be specified")
        if not hasattr(self, "output_path"):
            raise InputError("Output folder should be specified")
        path = os.path.join(self.output_path, file_prefix)
        exec_path = path + ".exec"
        ctx = self.data.get_images().get_voxelplan()
        if idx == 0:
            self.plan.save_data(ctx, path)
            self.plan.save_exec(ctx, exec_path)
        elif idx == 1:
            self.plan.save_exec(ctx, exec_path)
        elif idx == 2:
            self.plan.save_data(ctx, path)
        self.Close()

    def close(self, evt):
        self.Close()
예제 #6
0
class CreateStructureDialog(wx.Dialog):
    def __init__(self):
        pre = wx.PreDialog()
        self.PostCreate(pre)

    def Init(self, parent):
        self.parent = parent
        self.notebook = XRCCTRL(self, "notebook")
        voxelplan_image = self.parent.data.get_images().get_voxelplan()
        center = [
            voxelplan_image.dimx / 2.0 * voxelplan_image.pixel_size,
            voxelplan_image.dimy / 2.0 * voxelplan_image.pixel_size,
            voxelplan_image.dimz / 2.0 * voxelplan_image.slice_distance
        ]

        self.txt_name = XRCCTRL(self, "txt_name")
        data = self.parent.data
        num = len(data.get_vois())
        num += 1
        self.txt_name.SetValue("ptv %d" % num)

        self.txt_x = XRCCTRL(self, "txt_x")
        self.txt_x.SetValue("%.1f" % center[0])

        self.txt_y = XRCCTRL(self, "txt_y")
        self.txt_y.SetValue("%.1f" % center[1])

        self.txt_z = XRCCTRL(self, "txt_z")
        self.txt_z.SetValue("%.1f" % center[2])

        # ini cube
        self.txt_width = XRCCTRL(self, "txt_width")
        self.txt_width.SetValue("50")

        self.txt_height = XRCCTRL(self, "txt_height")
        self.txt_height.SetValue("50")

        self.txt_depth = XRCCTRL(self, "txt_depth")
        self.txt_depth.SetValue("50")

        # ini cylinder
        self.txt_cylinder_radius = XRCCTRL(self, "txt_cylinder_radius")
        self.txt_cylinder_radius.SetValue("50")

        self.txt_cylinder_depth = XRCCTRL(self, "txt_cylinder_depth")
        self.txt_cylinder_depth.SetValue("40")

        # ini sphere
        self.txt_sphere_radius = XRCCTRL(self, "txt_sphere_radius")
        self.txt_sphere_radius.SetValue("25")

        wx.EVT_BUTTON(self, XRCID("btn_create"), self.submit)
        wx.EVT_BUTTON(self, XRCID("btn_cancel"), self.close)

    def close(self, evt):
        self.Close()

    def submit(self, evt):
        name = self.txt_name.GetValue()
        x = float(self.txt_x.GetValue())
        y = float(self.txt_y.GetValue())
        z = float(self.txt_z.GetValue())

        voi_type = self.notebook.GetCurrentPage().GetName()

        # cube
        width = float(self.txt_width.GetValue())
        height = float(self.txt_height.GetValue())
        depth = float(self.txt_depth.GetValue())

        # cylinder
        cylinder_radius = float(self.txt_cylinder_radius.GetValue())
        cylinder_depth = float(self.txt_cylinder_depth.GetValue())

        # sphere
        sphere_radius = float(self.txt_sphere_radius.GetValue())

        if voi_type == "panel_cube":
            voi = create_cube(self.parent.data.get_images().get_voxelplan(),
                              name, [x, y, z], width, height, depth)
        elif voi_type == "panel_cylinder":
            voi = create_cylinder(
                self.parent.data.get_images().get_voxelplan(), name, [x, y, z],
                cylinder_radius, cylinder_depth)
        elif voi_type == "panel_sphere":
            voi = create_sphere(self.parent.data.get_images().get_voxelplan(),
                                name, [x, y, z], sphere_radius)
        self.parent.data.load_voi(voi, True)
        self.Close()
예제 #7
0
파일: dvh.py 프로젝트: leesei/dicompyler
class pluginDVH(wx.Panel):
    """Plugin to display DVH data with adjustable constraints."""
    def __init__(self):
        wx.Panel.__init__(self)

    def Init(self, res):
        """Method called after the panel has been initialized."""

        self.guiDVH = guidvh.guiDVH(self)
        res.AttachUnknownControl("panelDVH", self.guiDVH.panelDVH, self)

        # Initialize the Constraint selector controls
        self.lblType = XRCCTRL(self, "lblType")
        self.choiceConstraint = XRCCTRL(self, "choiceConstraint")
        self.txtConstraint = XRCCTRL(self, "txtConstraint")
        self.sliderConstraint = XRCCTRL(self, "sliderConstraint")
        self.lblResultType = XRCCTRL(self, "lblResultType")
        self.lblConstraintUnits = XRCCTRL(self, "lblConstraintUnits")
        self.lblConstraintTypeUnits = XRCCTRL(self, "lblConstraintTypeUnits")

        # Initialize the result labels
        self.lblConstraintType = XRCCTRL(self, "lblConstraintType")
        self.lblResultDivider = XRCCTRL(self, "lblResultDivider")
        self.lblConstraintPercent = XRCCTRL(self, "lblConstraintPercent")

        # Modify the control and font size on Mac
        controls = [
            self.lblType,
            self.choiceConstraint,
            self.sliderConstraint,
            self.lblResultType,
            self.lblConstraintUnits,
            self.lblConstraintPercent,
            self.lblConstraintType,
            self.lblConstraintTypeUnits,
            self.lblResultDivider,
        ]
        # Add children of composite controls to modification list
        compositecontrols = [self.txtConstraint]
        for control in compositecontrols:
            for child in control.GetChildren():
                controls.append(child)
        # Add the constraint static box to the modification list
        controls.append(self.lblType.GetContainingSizer().GetStaticBox())

        if guiutil.IsMac():
            for control in controls:
                control.SetWindowVariant(wx.WINDOW_VARIANT_SMALL)

        # Adjust the control size for the result value labels
        te = self.lblType.GetTextExtent("0")
        self.lblConstraintUnits.SetMinSize((te[0] * 10, te[1]))
        self.lblConstraintPercent.SetMinSize((te[0] * 6, te[1]))
        self.Layout()

        # Bind ui events to the proper methods
        self.Bind(wx.EVT_CHOICE,
                  self.OnToggleConstraints,
                  id=XRCID("choiceConstraint"))
        self.Bind(wx.EVT_SPINCTRL,
                  self.OnChangeConstraint,
                  id=XRCID("txtConstraint"))
        self.Bind(
            wx.EVT_COMMAND_SCROLL_THUMBTRACK,
            self.OnChangeConstraint,
            id=XRCID("sliderConstraint"),
        )
        self.Bind(
            wx.EVT_COMMAND_SCROLL_CHANGED,
            self.OnChangeConstraint,
            id=XRCID("sliderConstraint"),
        )
        self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy)

        # Initialize variables
        self.structures = {}  # structures from initial DICOM data
        self.checkedstructures = {}  # structures that need to be shown
        self.dvhs = {}  # raw dvhs from initial DICOM data
        self.dvharray = {}  # dict of dvh data processed from dvhdata
        self.dvhscaling = {}  # dict of dvh scaling data
        self.plan = {}  # used for rx dose
        self.structureid = 1  # used to indicate current constraint structure

        # Set up pubsub
        pub.subscribe(self.OnUpdatePatient, "patient.updated.parsed_data")
        pub.subscribe(self.OnStructureCheck, "structures.checked")
        pub.subscribe(self.OnStructureSelect, "structure.selected")

    def OnUpdatePatient(self, msg):
        """Update and load the patient data."""

        self.structures = msg["structures"]
        self.dvhs = msg["dvhs"]
        self.plan = msg["plan"]
        # show an empty plot when (re)loading a patient
        self.guiDVH.Replot()
        self.EnableConstraints(False)

    def OnDestroy(self, evt):
        """Unbind to all events before the plugin is destroyed."""

        pub.unsubscribe(self.OnUpdatePatient, "patient.updated.parsed_data")
        pub.unsubscribe(self.OnStructureCheck, "structures.checked")
        pub.unsubscribe(self.OnStructureSelect, "structure.selected")

    def OnStructureCheck(self, msg):
        """When a structure changes, update the interface and plot."""

        # Make sure that the volume has been calculated for each structure
        # before setting it
        self.checkedstructures = msg
        for id, structure in self.checkedstructures.items():
            if not "volume" in self.structures[id]:
                self.structures[id]["volume"] = structure["volume"]

            # make sure that the dvh has been calculated for each structure
            # before setting it
            if id in self.dvhs:
                self.EnableConstraints(True)
                self.dvharray[id] = self.dvhs[id].relative_volume.counts
                # Create an instance of the dvh scaling data for guidvh
                self.dvhscaling[id] = 1  # self.dvhs[id]['scaling']
                # 'Toggle' the choice box to refresh the dose data
                self.OnToggleConstraints(None)
        if not len(self.checkedstructures):
            self.EnableConstraints(False)
            # Make an empty plot on the DVH
            self.guiDVH.Replot()

    def OnStructureSelect(self, msg):
        """Load the constraints for the currently selected structure."""

        if msg["id"] == None:
            self.EnableConstraints(False)
        else:
            self.structureid = msg["id"]
            if self.structureid in self.dvhs:
                # Create an instance of the dvh scaling data for guidvh
                self.dvhscaling[
                    self.
                    structureid] = 1  # self.dvhs[self.structureid]['scaling']
                # 'Toggle' the choice box to refresh the dose data
                self.OnToggleConstraints(None)
            else:
                self.EnableConstraints(False)
                self.guiDVH.Replot([self.dvharray], [self.dvhscaling],
                                   self.checkedstructures)

    def EnableConstraints(self, value):
        """Enable or disable the constraint selector."""

        self.choiceConstraint.Enable(value)
        self.txtConstraint.Enable(value)
        self.sliderConstraint.Enable(value)
        if not value:
            self.lblConstraintUnits.SetLabel("- ")
            self.lblConstraintPercent.SetLabel("- ")
            self.txtConstraint.SetValue(0)
            self.sliderConstraint.SetValue(0)

    def OnToggleConstraints(self, evt):
        """Switch between different constraint modes."""

        # Replot the remaining structures and disable the constraints
        # if a structure that has no DVH calculated is selected
        if not self.structureid in self.dvhs:
            self.guiDVH.Replot([self.dvharray], [self.dvhscaling],
                               self.checkedstructures)
            self.EnableConstraints(False)
            return
        else:
            self.EnableConstraints(True)
            dvh = self.dvhs[self.structureid]

        # Check if the function was called via an event or not
        if not (evt == None):
            constrainttype = evt.GetInt()
        else:
            constrainttype = self.choiceConstraint.GetSelection()

        constraintrange = 0
        # Volume constraint
        if constrainttype == 0:
            self.lblConstraintType.SetLabel("   Dose:")
            self.lblConstraintTypeUnits.SetLabel("%  ")
            self.lblResultType.SetLabel("Volume:")
            constraintrange = dvh.relative_dose().max
        # Volume constraint in Gy
        elif constrainttype == 1:
            self.lblConstraintType.SetLabel("   Dose:")
            self.lblConstraintTypeUnits.SetLabel("Gy ")
            self.lblResultType.SetLabel("Volume:")
            constraintrange = round(dvh.max)
        # Dose constraint
        elif constrainttype == 2:
            self.lblConstraintType.SetLabel("Volume:")
            self.lblConstraintTypeUnits.SetLabel("%  ")
            self.lblResultType.SetLabel("   Dose:")
            constraintrange = 100
        # Dose constraint in cc
        elif constrainttype == 3:
            self.lblConstraintType.SetLabel("Volume:")
            self.lblConstraintTypeUnits.SetLabel("cm\u00B3")
            self.lblResultType.SetLabel("   Dose:")
            constraintrange = dvh.volume

        self.sliderConstraint.SetRange(0, constraintrange)
        self.sliderConstraint.SetValue(constraintrange)
        self.txtConstraint.SetRange(0, constraintrange)
        self.txtConstraint.SetValue(constraintrange)

        self.OnChangeConstraint(None)

    def OnChangeConstraint(self, evt):
        """Update the results when the constraint value changes."""

        # Check if the function was called via an event or not
        if not (evt == None):
            slidervalue = evt.GetInt()
        else:
            slidervalue = self.sliderConstraint.GetValue()

        self.txtConstraint.SetValue(slidervalue)
        self.sliderConstraint.SetValue(slidervalue)
        id = self.structureid
        dvh = self.dvhs[self.structureid]

        constrainttype = self.choiceConstraint.GetSelection()
        # Volume constraint
        if constrainttype == 0:
            absDose = dvh.rx_dose * slidervalue
            cc = dvh.volume_constraint(slidervalue)
            constraint = dvh.relative_volume.volume_constraint(slidervalue)

            self.lblConstraintUnits.SetLabel(str(cc))
            self.lblConstraintPercent.SetLabel(str(constraint))
            self.guiDVH.Replot(
                [self.dvharray],
                [self.dvhscaling],
                self.checkedstructures,
                ([absDose], [constraint.value]),
                id,
            )
        # Volume constraint in Gy
        elif constrainttype == 1:
            absDose = slidervalue * 100
            cc = dvh.volume_constraint(slidervalue, dvh.dose_units)
            constraint = dvh.relative_volume.volume_constraint(
                slidervalue, dvh.dose_units)

            self.lblConstraintUnits.SetLabel(str(cc))
            self.lblConstraintPercent.SetLabel(str(constraint))
            self.guiDVH.Replot(
                [self.dvharray],
                [self.dvhscaling],
                self.checkedstructures,
                ([absDose], [constraint.value]),
                id,
            )
        # Dose constraint
        elif constrainttype == 2:
            dose = dvh.dose_constraint(slidervalue)
            relative_dose = dvh.relative_dose().dose_constraint(slidervalue)

            self.lblConstraintUnits.SetLabel(str(dose))
            self.lblConstraintPercent.SetLabel(str(relative_dose))
            self.guiDVH.Replot(
                [self.dvharray],
                [self.dvhscaling],
                self.checkedstructures,
                ([dose.value * 100], [slidervalue]),
                id,
            )
        # Dose constraint in cc
        elif constrainttype == 3:
            volumepercent = slidervalue * 100 / self.structures[id]["volume"]
            dose = dvh.dose_constraint(slidervalue, dvh.volume_units)
            relative_dose = dvh.relative_dose().dose_constraint(
                slidervalue, dvh.volume_units)

            self.lblConstraintUnits.SetLabel(str(dose))
            self.lblConstraintPercent.SetLabel(str(relative_dose))
            self.guiDVH.Replot(
                [self.dvharray],
                [self.dvhscaling],
                self.checkedstructures,
                ([dose.value * 100], [volumepercent]),
                id,
            )
예제 #8
0
class TripVoiDialog(wx.Dialog):
    def __init__(self):
        pre = wx.PreDialog()
        self.PostCreate(pre)
        pub.subscribe(self.patient_data_updated, "patient.loaded")
        pub.sendMessage("patient.request", {})

    def patient_data_updated(self, msg):
        self.data = msg.data

    def select_drop_by_value(self, drop, value):
        for i, item in enumerate(drop.GetItems()):
            if item == value:
                drop.SetSelection(i)

    def Init(self, voi):
        self.voi = voi

        wx.EVT_BUTTON(self, XRCID('btn_ok'), self.save_and_close)
        wx.EVT_BUTTON(self, XRCID('btn_close'), self.close)

        self.label_name = XRCCTRL(self, "label_name")
        self.label_name.SetLabel(voi.get_name())

        self.txt_dose = XRCCTRL(self, "txt_dose")
        self.txt_dose.SetValue("%.2f" % (voi.get_dose()))

        self.check_target = XRCCTRL(self, "check_target")
        self.check_target.SetValue(voi.is_target())
        self.check_target.Bind(wx.EVT_CHECKBOX, self.on_check_target_changed)

        self.check_oar = XRCCTRL(self, "check_oar")
        self.check_oar.SetValue(voi.is_oar())
        self.check_oar.Bind(wx.EVT_CHECKBOX, self.on_check_oar_changed)

        self.txt_max_dose_fraction = XRCCTRL(self, "txt_max_dose_fraction")
        self.txt_max_dose_fraction.SetValue("%.2f" % (voi.get_max_dose_fraction()))

        self.txt_max_dose_fraction.Enable(False)
        self.txt_dose.Enable(False)
        if voi.is_target():
            self.check_oar.Enable(False)
            self.txt_dose.Enable(True)

        if voi.is_oar():
            self.txt_max_dose_fraction.Enable(True)
            self.check_target.Enable(False)

        self.txt_hu_value = XRCCTRL(self, "txt_hu_value")
        self.txt_hu_offset = XRCCTRL(self, "txt_hu_offset")
        if not voi.get_hu_value() is None:
            self.txt_hu_value.SetValue("%d" % voi.get_hu_value())
        if not voi.get_hu_offset() is None:
            self.txt_hu_offset.SetValue("%d" % voi.get_hu_offset())

        self.drop_projectile = XRCCTRL(self, "drop_projectile")
        self.drop_projectile.Append("H")
        self.drop_projectile.Append("C")

        self.txt_dose_percent = XRCCTRL(self, "txt_dose_percent")
        wx.EVT_BUTTON(self, XRCID('btn_set_dosepercent'), self.set_dose_percent)
        wx.EVT_CHOICE(self, XRCID('drop_projectile'), self.on_projectile_changed)

    def on_projectile_changed(self, evt):
        projectile = self.drop_projectile.GetStringSelection()
        dose_percent = self.voi.get_dose_percent(projectile)
        if dose_percent is None:
            self.txt_dose_percent.SetValue("")
        else:
            self.txt_dose_percent.SetValue("%d" % dose_percent)

    def set_dose_percent(self, evt):
        if not self.drop_projectile.GetStringSelection() == "":
            self.voi.set_dose_percent(self.drop_projectile.GetStringSelection(), self.txt_dose_percent.GetValue())

    def on_check_target_changed(self, evt):
        if evt.Checked():
            self.check_oar.Enable(False)
            self.txt_dose.Enable(True)
        else:
            self.check_oar.Enable(True)
            self.txt_dose.Enable(False)

    def on_check_oar_changed(self, evt):
        if evt.Checked():
            self.txt_max_dose_fraction.Enable(True)
            self.check_target.Enable(False)
        else:
            self.check_target.Enable(True)
            self.txt_max_dose_fraction.Enable(False)

    def save_and_close(self, evt):
        voi = self.voi
        voi.set_dose(self.txt_dose.GetValue())
        if voi.is_target() is not self.check_target.IsChecked():
            voi.toogle_target()
        if voi.is_oar() is not self.check_oar.IsChecked():
            voi.toogle_oar()
        voi.set_max_dose_fraction(self.txt_max_dose_fraction.GetValue())
        voi.set_hu_offset(self.txt_hu_offset.GetValue())
        voi.set_hu_value(self.txt_hu_value.GetValue())

        self.Close()

    def close(self, evt):
        self.Close()
예제 #9
0
class TripExportCubeDialog(wx.Dialog):
    def __init__(self):
        pre = wx.PreDialog()
        self.PostCreate(pre)

    def Init(self, plan):
        self.plan = plan
        self.path = "~/"
        self.output_path = ""
        self.checkbox_vois = XRCCTRL(self, "checkbox_vois")
        wx.EVT_LISTBOX(self, XRCID("checkbox_vois"), self.selected_changed)
        wx.EVT_BUTTON(self, XRCID("btn_ok"), self.save_and_close)
        wx.EVT_BUTTON(self, XRCID("btn_cancel"), self.close)
        wx.EVT_BUTTON(self, XRCID("btn_reset"), self.reset)

        self.lbl_path = XRCCTRL(self, "lbl_path")
        self.txt_value = XRCCTRL(self, "txt_value")
        wx.EVT_TEXT(self, XRCID("txt_value"), self.text_value_changed)

        pub.subscribe(self.path_changed, "general.export.cube_export_path")
        pub.sendMessage("settings.value.request", "general.export.cube")
        pub.subscribe(self.patient_data_updated, "patient.loaded")
        pub.sendMessage("patient.request", {})
        for voi in plan.get_vois():
            self.checkbox_vois.Append(voi.get_name())

    def patient_data_updated(self, msg):
        self.data = msg.data

    def selected_changed(self, evt):
        selected = self.checkbox_vois.GetStringSelection()
        self.txt_value.SetValue("")
        for voi in self.plan.get_vois():

            if selected == voi.get_name():
                if voi.get_cube_value() is -1:
                    self.txt_value.SetValue("")
                else:
                    self.txt_value.SetValue("%d" % voi.get_cube_value())

    def text_value_changed(self, evt):
        selected = self.checkbox_vois.GetStringSelection()
        if len(selected) is 0:
            return
        for voi in self.plan.get_vois():
            if selected == voi.get_name():
                try:
                    voi.set_cube_value(int(self.txt_value.GetValue()))
                except Exception as e:
                    pass

    def path_changed(self, msg):
        if not msg.data is None:
            self.path = msg.data
            self.lbl_path.SetLabel(self.path)

    def reset(self, evt):
        for voi in self.plan.get_vois():
            voi.set_cube_value(-1)
        self.txt_value.SetValue("")
        for k, item in enumerate(self.checkbox_vois.GetItems()):
            self.checkbox_vois.Check(k, False)

    def browse_for_file(self):
        dlg = wx.FileDialog(self,
                            message="Save Picture",
                            defaultDir=self.path,
                            style=wx.FD_SAVE)
        if dlg.ShowModal() == wx.ID_OK:
            path = dlg.GetPath()
            a = os.path.splitext(path)
            if not a[-1] is "dos":
                path = path + ".dos"
                self.output_path = path
                pub.sendMessage("settings.value.updated",
                                {"general.export.cube": os.path.dirname(path)})
            return True
        return False

    def save_and_close(self, evt):
        selected = self.checkbox_vois.GetCheckedStrings()
        vois = []
        dos = None
        for voi in self.plan.get_vois():
            if voi.get_name() in selected:
                if dos is None:
                    dos = voi.get_voi().get_voi_data().get_voi_cube(
                    ) / 1000 * voi.get_cube_value()
                else:
                    dos.cube[dos.cube == 0] = -1
                    a = voi.get_voi().get_voi_data().get_voi_cube(
                    ) / 1000 * voi.get_cube_value()
                    dos.cube[dos.cube == -1] = a.cube[dos.cube == -1]

        if not dos is None:
            if self.browse_for_file():
                dos.write(self.output_path)
            else:
                return
        else:
            pass

        self.Close()

    def close(self, evt):
        self.Close()
예제 #10
0
파일: dvh.py 프로젝트: tparpaite/dicompyler
class pluginDVH(wx.Panel):
    """Plugin to display DVH data with adjustable constraints."""
    def __init__(self):
        pre = wx.PrePanel()
        # the Create step is done by XRC.
        self.PostCreate(pre)

    def Init(self, res):
        """Method called after the panel has been initialized."""

        self.guiDVH = guidvh.guiDVH(self)
        res.AttachUnknownControl('panelDVH', self.guiDVH.panelDVH, self)

        # Initialize the Constraint selector controls
        self.lblType = XRCCTRL(self, 'lblType')
        self.choiceConstraint = XRCCTRL(self, 'choiceConstraint')
        self.txtConstraint = XRCCTRL(self, 'txtConstraint')
        self.sliderConstraint = XRCCTRL(self, 'sliderConstraint')
        self.lblResultType = XRCCTRL(self, 'lblResultType')
        self.lblConstraintUnits = XRCCTRL(self, 'lblConstraintUnits')
        self.lblConstraintTypeUnits = XRCCTRL(self, 'lblConstraintTypeUnits')

        # Initialize the result labels
        self.lblConstraintType = XRCCTRL(self, 'lblConstraintType')
        self.lblResultDivider = XRCCTRL(self, 'lblResultDivider')
        self.lblConstraintPercent = XRCCTRL(self, 'lblConstraintPercent')

        # Modify the control and font size on Mac
        controls = [
            self.lblType, self.choiceConstraint, self.sliderConstraint,
            self.lblResultType, self.lblConstraintUnits,
            self.lblConstraintPercent, self.lblConstraintType,
            self.lblConstraintTypeUnits, self.lblResultDivider
        ]
        # Add children of composite controls to modification list
        compositecontrols = [self.txtConstraint]
        for control in compositecontrols:
            for child in control.GetChildren():
                controls.append(child)
        # Add the constraint static box to the modification list
        controls.append(self.lblType.GetContainingSizer().GetStaticBox())

        if guiutil.IsMac():
            font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
            font.SetPointSize(10)
            for control in controls:
                control.SetWindowVariant(wx.WINDOW_VARIANT_SMALL)
                control.SetFont(font)

        # Adjust the control size for the result value labels
        te = self.lblType.GetTextExtent('0')
        self.lblConstraintUnits.SetMinSize((te[0] * 10, te[1]))
        self.lblConstraintPercent.SetMinSize((te[0] * 6, te[1]))
        self.Layout()

        # Bind ui events to the proper methods
        wx.EVT_CHOICE(self, XRCID('choiceConstraint'),
                      self.OnToggleConstraints)
        wx.EVT_SPINCTRL(self, XRCID('txtConstraint'), self.OnChangeConstraint)
        wx.EVT_COMMAND_SCROLL_THUMBTRACK(self, XRCID('sliderConstraint'),
                                         self.OnChangeConstraint)
        wx.EVT_COMMAND_SCROLL_CHANGED(self, XRCID('sliderConstraint'),
                                      self.OnChangeConstraint)
        self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy)

        # Initialize variables
        self.structures = {}  # structures from initial DICOM data
        self.checkedstructures = {}  # structures that need to be shown
        self.dvhs = {}  # raw dvhs from initial DICOM data
        self.dvhdata = {}  # dict of dvh constraint functions
        self.dvharray = {}  # dict of dvh data processed from dvhdata
        self.dvhscaling = {}  # dict of dvh scaling data
        self.plan = {}  # used for rx dose
        self.structureid = 1  # used to indicate current constraint structure

        # Set up pubsub
        pub.subscribe(self.OnUpdatePatient, 'patient.updated.parsed_data')
        pub.subscribe(self.OnStructureCheck, 'structures.checked')
        pub.subscribe(self.OnStructureSelect, 'structure.selected')

    def OnUpdatePatient(self, msg):
        """Update and load the patient data."""

        self.structures = msg.data['structures']
        self.dvhs = msg.data['dvhs']
        self.plan = msg.data['plan']
        # show an empty plot when (re)loading a patient
        self.guiDVH.Replot()
        self.EnableConstraints(False)

    def OnDestroy(self, evt):
        """Unbind to all events before the plugin is destroyed."""

        pub.unsubscribe(self.OnUpdatePatient)
        pub.unsubscribe(self.OnStructureCheck)
        pub.unsubscribe(self.OnStructureSelect)

    def OnStructureCheck(self, msg):
        """When a structure changes, update the interface and plot."""

        # Make sure that the volume has been calculated for each structure
        # before setting it
        self.checkedstructures = msg.data
        for id, structure in self.checkedstructures.iteritems():
            if not self.structures[id].has_key('volume'):
                self.structures[id]['volume'] = structure['volume']

            # make sure that the dvh has been calculated for each structure
            # before setting it
            if self.dvhs.has_key(id):
                self.EnableConstraints(True)
                # Create an instance of the dvhdata class to can access its functions
                self.dvhdata[id] = dvhdata.DVH(self.dvhs[id])
                # Create an instance of the dvh arrays so that guidvh can plot it
                self.dvharray[id] = dvhdata.DVH(self.dvhs[id]).dvh
                # Create an instance of the dvh scaling data for guidvh
                self.dvhscaling[id] = self.dvhs[id]['scaling']
                # 'Toggle' the choice box to refresh the dose data
                self.OnToggleConstraints(None)
        if not len(self.checkedstructures):
            self.EnableConstraints(False)
            # Make an empty plot on the DVH
            self.guiDVH.Replot()

    def OnStructureSelect(self, msg):
        """Load the constraints for the currently selected structure."""

        if (msg.data['id'] == None):
            self.EnableConstraints(False)
        else:
            self.structureid = msg.data['id']
            if self.dvhs.has_key(self.structureid):
                # Create an instance of the dvhdata class to can access its functions
                self.dvhdata[self.structureid] = dvhdata.DVH(
                    self.dvhs[self.structureid])
                # Create an instance of the dvh scaling data for guidvh
                self.dvhscaling[self.structureid] = self.dvhs[
                    self.structureid]['scaling']
                # 'Toggle' the choice box to refresh the dose data
                self.OnToggleConstraints(None)
            else:
                self.EnableConstraints(False)
                self.guiDVH.Replot([self.dvharray], [self.dvhscaling],
                                   self.checkedstructures)

    def EnableConstraints(self, value):
        """Enable or disable the constraint selector."""

        self.choiceConstraint.Enable(value)
        self.txtConstraint.Enable(value)
        self.sliderConstraint.Enable(value)
        if not value:
            self.lblConstraintUnits.SetLabel('- ')
            self.lblConstraintPercent.SetLabel('- ')
            self.txtConstraint.SetValue(0)
            self.sliderConstraint.SetValue(0)

    def OnToggleConstraints(self, evt):
        """Switch between different constraint modes."""

        # Replot the remaining structures and disable the constraints
        # if a structure that has no DVH calculated is selected
        if not self.dvhs.has_key(self.structureid):
            self.guiDVH.Replot([self.dvharray], [self.dvhscaling],
                               self.checkedstructures)
            self.EnableConstraints(False)
            return
        else:
            self.EnableConstraints(True)
            dvh = self.dvhs[self.structureid]

        # Check if the function was called via an event or not
        if not (evt == None):
            constrainttype = evt.GetInt()
        else:
            constrainttype = self.choiceConstraint.GetSelection()

        constraintrange = 0
        # Volume constraint
        if (constrainttype == 0):
            self.lblConstraintType.SetLabel('   Dose:')
            self.lblConstraintTypeUnits.SetLabel('%  ')
            self.lblResultType.SetLabel('Volume:')
            rxDose = float(self.plan['rxdose'])
            dvhdata = (len(dvh['data']) - 1) * dvh['scaling']
            constraintrange = int(dvhdata * 100 / rxDose)
            # never go over the max dose as data does not exist
            if (constraintrange > int(dvh['max'])):
                constraintrange = int(dvh['max'])
        # Volume constraint in Gy
        elif (constrainttype == 1):
            self.lblConstraintType.SetLabel('   Dose:')
            self.lblConstraintTypeUnits.SetLabel('Gy ')
            self.lblResultType.SetLabel('Volume:')
            constraintrange = self.plan['rxdose'] / 100
            maxdose = int(dvh['max'] * self.plan['rxdose'] / 10000)
            # never go over the max dose as data does not exist
            if (constraintrange * 100 > maxdose):
                constraintrange = maxdose
        # Dose constraint
        elif (constrainttype == 2):
            self.lblConstraintType.SetLabel('Volume:')
            self.lblConstraintTypeUnits.SetLabel(u'%  ')
            self.lblResultType.SetLabel('   Dose:')
            constraintrange = 100
        # Dose constraint in cc
        elif (constrainttype == 3):
            self.lblConstraintType.SetLabel('Volume:')
            self.lblConstraintTypeUnits.SetLabel(u'cm³')
            self.lblResultType.SetLabel('   Dose:')
            constraintrange = int(self.structures[self.structureid]['volume'])

        self.sliderConstraint.SetRange(0, constraintrange)
        self.sliderConstraint.SetValue(constraintrange)
        self.txtConstraint.SetRange(0, constraintrange)
        self.txtConstraint.SetValue(constraintrange)

        self.OnChangeConstraint(None)

    def OnChangeConstraint(self, evt):
        """Update the results when the constraint value changes."""

        # Check if the function was called via an event or not
        if not (evt == None):
            slidervalue = evt.GetInt()
        else:
            slidervalue = self.sliderConstraint.GetValue()

        self.txtConstraint.SetValue(slidervalue)
        self.sliderConstraint.SetValue(slidervalue)
        rxDose = self.plan['rxdose']
        id = self.structureid

        constrainttype = self.choiceConstraint.GetSelection()
        # Volume constraint
        if (constrainttype == 0):
            absDose = rxDose * slidervalue / 100
            volume = self.structures[id]['volume']
            cc = self.dvhdata[id].GetVolumeConstraintCC(absDose, volume)
            constraint = self.dvhdata[id].GetVolumeConstraint(absDose)

            self.lblConstraintUnits.SetLabel("%.1f" % cc + u' cm³')
            self.lblConstraintPercent.SetLabel("%.1f" % constraint + " %")
            self.guiDVH.Replot([self.dvharray], [self.dvhscaling],
                               self.checkedstructures,
                               ([absDose], [constraint]), id)
        # Volume constraint in Gy
        elif (constrainttype == 1):
            absDose = slidervalue * 100
            volume = self.structures[id]['volume']
            cc = self.dvhdata[id].GetVolumeConstraintCC(absDose, volume)
            constraint = self.dvhdata[id].GetVolumeConstraint(absDose)

            self.lblConstraintUnits.SetLabel("%.1f" % cc + u' cm³')
            self.lblConstraintPercent.SetLabel("%.1f" % constraint + " %")
            self.guiDVH.Replot([self.dvharray], [self.dvhscaling],
                               self.checkedstructures,
                               ([absDose], [constraint]), id)
        # Dose constraint
        elif (constrainttype == 2):
            dose = self.dvhdata[id].GetDoseConstraint(slidervalue)

            self.lblConstraintUnits.SetLabel("%.1f" % dose + u' cGy')
            self.lblConstraintPercent.SetLabel("%.1f" % (dose * 100 / rxDose) +
                                               " %")
            self.guiDVH.Replot([self.dvharray], [self.dvhscaling],
                               self.checkedstructures, ([dose], [slidervalue]),
                               id)
        # Dose constraint in cc
        elif (constrainttype == 3):
            volumepercent = slidervalue * 100 / self.structures[id]['volume']

            dose = self.dvhdata[id].GetDoseConstraint(volumepercent)

            self.lblConstraintUnits.SetLabel("%.1f" % dose + u' cGy')
            self.lblConstraintPercent.SetLabel("%.1f" % (dose * 100 / rxDose) +
                                               " %")
            self.guiDVH.Replot([self.dvharray], [self.dvhscaling],
                               self.checkedstructures,
                               ([dose], [volumepercent]), id)
예제 #11
0
class AnonymizeDialog(wx.Dialog):
    """Dialog th                                # Changed foundstructure to fixed 'True'
                                # I didn't understand the reason why RT Structure Set will be
                                # set to 'not found' in this case. (Actually RT Structure has already been found by the above code.)
                                # In this case, 'RT Plan' is not found, RT Structure Set in patient, and foundstructure = False.
# Previous code: foundstructure = Falseat shows the options to anonymize DICOM / DICOM RT data."""
    def __init__(self):
        wx.Dialog.__init__(self)

    def Init(self):
        """Method called after the dialog has been initialized."""

        # Set window icon
        if not guiutil.IsMac():
            self.SetIcon(guiutil.get_icon())

        # Initialize controls
        self.txtDICOMFolder = XRCCTRL(self, 'txtDICOMFolder')
        self.checkPatientName = XRCCTRL(self, 'checkPatientName')
        self.txtFirstName = XRCCTRL(self, 'txtFirstName')
        self.txtLastName = XRCCTRL(self, 'txtLastName')
        self.checkPatientID = XRCCTRL(self, 'checkPatientID')
        self.txtPatientID = XRCCTRL(self, 'txtPatientID')
        self.checkPrivateTags = XRCCTRL(self, 'checkPrivateTags')
        self.bmpError = XRCCTRL(self, 'bmpError')
        self.lblDescription = XRCCTRL(self, 'lblDescription')

        # Bind interface events to the proper methods
        wx.EVT_BUTTON(self, XRCID('btnFolderBrowse'), self.OnFolderBrowse)
        wx.EVT_CHECKBOX(self, XRCID('checkPatientName'),
                        self.OnCheckPatientName)
        wx.EVT_CHECKBOX(self, XRCID('checkPatientID'), self.OnCheckPatientID)
        wx.EVT_BUTTON(self, wx.ID_OK, self.OnOK)

        # Set and bold the font of the description label
        if guiutil.IsMac():
            font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
            font.SetWeight(wx.FONTWEIGHT_BOLD)
            self.lblDescription.SetFont(font)

        # Initialize the import location via pubsub
        pub.subscribe(self.OnImportPrefsChange, 'general.dicom')
        pub.sendMessage('preferences.requested.values', msg='general.dicom')

        # Pre-select the text on the text controls due to a Mac OS X bug
        self.txtFirstName.SetSelection(-1, -1)
        self.txtLastName.SetSelection(-1, -1)
        self.txtPatientID.SetSelection(-1, -1)

        # Load the error bitmap
        self.bmpError.SetBitmap(wx.Bitmap(util.GetResourcePath('error.png')))

        # Initialize variables
        self.name = self.txtLastName.GetValue(
        ) + '^' + self.txtFirstName.GetValue()
        self.patientid = self.txtPatientID.GetValue()
        self.privatetags = True

    def OnImportPrefsChange(self, topic, msg):
        """When the import preferences change, update the values."""
        topic = topic.split('.')
        if (topic[1] == 'import_location'):
            self.path = str(msg)
            self.txtDICOMFolder.SetValue(self.path)

    def OnFolderBrowse(self, evt):
        """Get the directory selected by the user."""

        dlg = wx.DirDialog(
            self,
            defaultPath=self.path,
            message="Choose a folder to save the anonymized DICOM data...")

        if dlg.ShowModal() == wx.ID_OK:
            self.path = dlg.GetPath()
            self.txtDICOMFolder.SetValue(self.path)

        dlg.Destroy()

    def OnCheckPatientName(self, evt):
        """Enable or disable whether the patient's name is anonymized."""

        self.txtFirstName.Enable(evt.IsChecked())
        self.txtLastName.Enable(evt.IsChecked())
        if not evt.IsChecked():
            self.txtDICOMFolder.SetFocus()
        else:
            self.txtFirstName.SetFocus()
            self.txtFirstName.SetSelection(-1, -1)

    def OnCheckPatientID(self, evt):
        """Enable or disable whether the patient's ID is anonymized."""

        self.txtPatientID.Enable(evt.IsChecked())
        if not evt.IsChecked():
            self.txtDICOMFolder.SetFocus()
        else:
            self.txtPatientID.SetFocus()
            self.txtPatientID.SetSelection(-1, -1)

    def OnOK(self, evt):
        """Return the options from the anonymize data dialog."""

        # Patient name
        if self.checkPatientName.IsChecked():
            self.name = self.txtLastName.GetValue()
            if len(self.txtFirstName.GetValue()):
                self.name = self.name + '^' + self.txtFirstName.GetValue()
        else:
            self.name = ''

        # Patient ID
        if self.checkPatientID.IsChecked():
            self.patientid = self.txtPatientID.GetValue()
        else:
            self.patientid = ''

        # Private tags
        if self.checkPrivateTags.IsChecked():
            self.privatetags = True
        else:
            self.privatetags = False

        self.EndModal(wx.ID_OK)
예제 #12
0
class FieldDialog(wx.Dialog):
    def __init__(self):
        pre = wx.PreDialog()
        self.PostCreate(pre)

    def Init(self, field):
        self.field = field
        self.btn_ok = XRCCTRL(self, 'btn_ok')
        wx.EVT_BUTTON(self, XRCID('btn_ok'), self.save_and_close)

        self.btn_cancel = XRCCTRL(self, 'btn_close')
        wx.EVT_BUTTON(self, XRCID('btn_close'), self.close)

        self.label_fieldname = XRCCTRL(self, 'label_fieldname')
        self.label_fieldname.SetLabel(field.get_name())

        self.check_isocenter = XRCCTRL(self, 'check_isocenter')
        target = field.get_target()
        if len(target) > 0:
            self.check_isocenter.SetValue(True)
        self.check_isocenter.Bind(wx.EVT_CHECKBOX,
                                  self.on_check_isocenter_changed)

        self.txt_targetx = XRCCTRL(self, 'txt_targetx')
        self.txt_targety = XRCCTRL(self, 'txt_targety')
        self.txt_targetz = XRCCTRL(self, 'txt_targetz')
        if len(target) > 0:
            self.txt_targetx.SetValue("%.2f" % (target[0]))
            self.txt_targety.SetValue("%.2f" % (target[1]))
            self.txt_targetz.SetValue("%.2f" % (target[2]))
        else:
            self.txt_targetx.Enable(False)
            self.txt_targety.Enable(False)
            self.txt_targetz.Enable(False)

        self.txt_gantry = XRCCTRL(self, 'txt_gantry')
        self.txt_gantry.SetValue("%.2f" % field.get_gantry())

        self.txt_couch = XRCCTRL(self, 'txt_couch')
        self.txt_couch.SetValue("%.2f" % field.get_couch())

        self.txt_fwhm = XRCCTRL(self, 'txt_fwhm')
        self.txt_fwhm.SetValue("%.2f" % field.get_fwhm())

        self.txt_zsteps = XRCCTRL(self, 'txt_zsteps')
        self.txt_zsteps.SetValue("%.2f" % field.get_zsteps())

        self.txt_doseextension = XRCCTRL(self, 'txt_doseext')
        self.txt_doseextension.SetValue("%.2f" % field.get_doseextension())

        self.txt_contourextension = XRCCTRL(self, 'txt_contourext')
        self.txt_contourextension.SetValue("%.2f" %
                                           field.get_contourextension())

        self.txt_raster1 = XRCCTRL(self, 'txt_raster1')
        self.txt_raster2 = XRCCTRL(self, 'txt_raster2')

        raster = field.get_rasterstep()
        self.txt_raster1.SetValue("%.2f" % raster[0])
        self.txt_raster2.SetValue("%.2f" % raster[1])

        self.drop_projectile = XRCCTRL(self, 'drop_projectile')
        self.drop_projectile.SetSelection(
            self.drop_projectile.GetItems().index(field.projectile))

    def on_check_isocenter_changed(self, evt):
        if self.check_isocenter.IsChecked():
            self.txt_targetx.Enable(True)
            self.txt_targety.Enable(True)
            self.txt_targetz.Enable(True)
        else:
            self.txt_targetx.Enable(False)
            self.txt_targety.Enable(False)
            self.txt_targetz.Enable(False)

    def save_and_close(self, evt):
        self.field.set_couch(self.txt_couch.GetValue())
        self.field.set_gantry(self.txt_gantry.GetValue())
        self.field.set_fwhm(self.txt_fwhm.GetValue())
        if self.check_isocenter.IsChecked():
            self.field.set_target(self.txt_targetx.GetValue() + "," +
                                  self.txt_targety.GetValue() + "," +
                                  self.txt_targetz.GetValue())
        else:
            self.field.set_target("")
        self.field.set_zsteps(self.txt_zsteps.GetValue())

        self.field.set_doseextension(self.txt_doseextension.GetValue())
        self.field.set_contourextension(self.txt_contourextension.GetValue())
        self.field.set_rasterstep(self.txt_raster1.GetValue(),
                                  self.txt_raster2.GetValue())
        self.field.set_projectile(self.drop_projectile.GetStringSelection())
        self.Close()

    def close(self, evt):
        self.Close()
예제 #13
0
class PlanDialog(wx.Dialog):
    def __init__(self):
        pre = wx.PreDialog()
        self.PostCreate(pre)
        pub.subscribe(self.patient_data_updated, "patient.loaded")
        pub.sendMessage("patient.request", {})

    def Init(self, plan):
        self.plan = plan

        self.btn_ok = XRCCTRL(self, 'btn_ok')
        wx.EVT_BUTTON(self, XRCID('btn_ok'), self.save_and_close)

        self.btn_cancel = XRCCTRL(self, 'btn_close')
        wx.EVT_BUTTON(self, XRCID('btn_close'), self.close)

        self.init_general()
        self.init_trip_panel()
        self.init_opt_panel()
        self.init_calculation_panel()
        self.init_files_panel()
        self.init_advanved_dose()

    def patient_data_updated(self, msg):
        self.data = msg.data

    def init_files_panel(self):
        self.txt_ddd = XRCCTRL(self, "txt_ddd")
        self.txt_ddd.SetValue(self.plan.get_ddd_folder())

        self.txt_spc = XRCCTRL(self, "txt_spc")
        self.txt_spc.SetValue(self.plan.get_spc_folder())

        self.txt_sis = XRCCTRL(self, "txt_sis")
        self.txt_sis.SetValue(self.plan.get_sis_file())

        wx.EVT_BUTTON(self, XRCID("btn_ddd"), self.on_btn_ddd_clicked)
        wx.EVT_BUTTON(self, XRCID("btn_spc"), self.on_btn_spc_clicked)
        wx.EVT_BUTTON(self, XRCID("btn_sis"), self.on_btn_sis_clicked)

    def init_general(self):
        self.drop_res_tissue_type = XRCCTRL(self, "drop_res_tissue_type")
        rbe_list = self.data.get_rbe()
        for rbe in rbe_list.get_rbe_list():
            self.drop_res_tissue_type.Append(rbe.get_name())
        self.select_drop_by_value(self.drop_res_tissue_type,
                                  self.plan.get_res_tissue_type())
        self.drop_target_tissue_type = XRCCTRL(self, "drop_target_tissue_type")
        for rbe in rbe_list.get_rbe_list():
            self.drop_target_tissue_type.Append(rbe.get_name())
        self.select_drop_by_value(self.drop_target_tissue_type,
                                  self.plan.get_target_tissue_type())

    def select_drop_by_value(self, drop, value):
        for i, item in enumerate(drop.GetItems()):
            if item == value:
                drop.SetSelection(i)

    def init_calculation_panel(self):
        self.check_phys_dose = XRCCTRL(self, "check_phys_dose")
        self.check_phys_dose.SetValue(self.plan.get_out_phys_dose())

        self.check_bio_dose = XRCCTRL(self, "check_bio_dose")
        self.check_bio_dose.SetValue(self.plan.get_out_bio_dose())

        self.check_dose_mean_let = XRCCTRL(self, "check_mean_let")
        self.check_dose_mean_let.SetValue(self.plan.get_out_dose_mean_let())

        self.check_field = XRCCTRL(self, "check_field")
        self.check_field.SetValue(self.plan.get_out_field())

    def init_opt_panel(self):
        self.txt_iterations = XRCCTRL(self, "txt_iterations")
        self.txt_iterations.SetValue("%d" % self.plan.get_iterations())

        self.txt_eps = XRCCTRL(self, "txt_eps")
        self.txt_eps.SetValue("%f" % self.plan.get_eps())

        self.txt_geps = XRCCTRL(self, "txt_geps")
        self.txt_geps.SetValue("%f" % self.plan.get_geps())

        self.drop_opt_method = XRCCTRL(self, "drop_opt_method")
        self.select_drop_by_value(self.drop_opt_method,
                                  self.plan.get_opt_method())

        self.drop_opt_principle = XRCCTRL(self, "drop_opt_principle")
        self.select_drop_by_value(self.drop_opt_principle,
                                  self.plan.get_opt_princip())

        self.drop_dose_alg = XRCCTRL(self, "drop_dose_alg")
        self.select_drop_by_value(self.drop_dose_alg,
                                  self.plan.get_dose_algorithm())

        self.drop_bio_alg = XRCCTRL(self, "drop_bio_alg")
        self.select_drop_by_value(self.drop_bio_alg,
                                  self.plan.get_dose_algorithm())

        self.drop_opt_alg = XRCCTRL(self, "drop_opt_alg")
        self.select_drop_by_value(self.drop_opt_alg,
                                  self.plan.get_opt_algorithm())

    def init_trip_panel(self):
        self.drop_location = XRCCTRL(self, "drop_location")
        if self.plan.is_remote():
            self.drop_location.SetSelection(1)

        self.txt_working_dir = XRCCTRL(self, "txt_working_dir")
        self.txt_working_dir.SetValue(self.plan.get_working_dir())

        wx.EVT_BUTTON(self, XRCID('btn_working_dir'),
                      self.on_browse_working_dir)

        self.txt_username = XRCCTRL(self, "txt_username")
        self.txt_username.SetValue(self.plan.get_username())

        self.txt_password = XRCCTRL(self, "txt_password")
        self.txt_password.SetValue(self.plan.get_password())

        self.txt_server = XRCCTRL(self, "txt_server")
        self.txt_server.SetValue(self.plan.get_server())

    def init_advanved_dose(self):
        self.drop_projectile = XRCCTRL(self, "drop_projectile")
        self.drop_projectile.Append("H")
        self.drop_projectile.Append("C")

        self.txt_dose_percent = XRCCTRL(self, "txt_dose_percent")
        wx.EVT_BUTTON(self, XRCID('btn_set_dosepercent'),
                      self.set_dose_percent)
        wx.EVT_CHOICE(self, XRCID('drop_projectile'),
                      self.on_projectile_changed)

    def on_projectile_changed(self, evt):
        projectile = self.drop_projectile.GetStringSelection()
        dose_percent = self.plan.get_dose_percent(projectile)
        if dose_percent is None:
            self.txt_dose_percent.SetValue("")
        else:
            self.txt_dose_percent.SetValue("%d" % dose_percent)

    def set_dose_percent(self, evt):
        if not self.drop_projectile.GetStringSelection() == "":
            self.plan.set_dose_percent(
                self.drop_projectile.GetStringSelection(),
                self.txt_dose_percent.GetValue())

    def on_browse_working_dir(self, evt):
        dlg = wx.DirDialog(
            self,
            defaultPath=self.txt_working_dir.GetValue(),
            message=
            "Choose the folder pytripgui should use as working directory")
        if dlg.ShowModal() == wx.ID_OK:
            self.txt_working_dir.SetValue(dlg.GetPath())

    def on_btn_ddd_clicked(self, evt):
        dlg = wx.DirDialog(self,
                           defaultPath=self.txt_ddd.GetValue(),
                           message="Choose folder where ddd files are located")
        if dlg.ShowModal() == wx.ID_OK:
            self.txt_ddd.SetValue(dlg.GetPath())

    def on_btn_sis_clicked(self, evt):
        dlg = wx.FileDialog(self,
                            defaultFile=self.txt_sis.GetValue(),
                            message="Choose sis file")
        if dlg.ShowModal() == wx.ID_OK:
            self.txt_sis.SetValue(dlg.GetPath())

    def on_btn_spc_clicked(self, evt):
        dlg = wx.DirDialog(self,
                           defaultPath=self.txt_spc.GetValue(),
                           message="Choose folder where spc files are located")
        if dlg.ShowModal() == wx.ID_OK:
            self.txt_spc.SetValue(dlg.GetPath())

    def save_and_close(self, evt):
        self.plan.set_res_tissue_type(
            self.drop_res_tissue_type.GetStringSelection())
        self.plan.set_target_tissue_type(
            self.drop_target_tissue_type.GetStringSelection())
        if self.drop_location.GetSelection() is 0:
            self.plan.set_remote_state(False)
        else:
            self.plan.set_remote_state(True)
        self.plan.set_working_dir(self.txt_working_dir.GetValue())
        self.plan.set_server(self.txt_server.GetValue())
        self.plan.set_username(self.txt_username.GetValue())
        self.plan.set_password(self.txt_password.GetValue())

        self.plan.set_iterations(self.txt_iterations.GetValue())
        self.plan.set_eps(self.txt_eps.GetValue())
        self.plan.set_geps(self.txt_geps.GetValue())
        self.plan.set_opt_method(self.drop_opt_method.GetStringSelection())
        self.plan.set_opt_princip(self.drop_opt_principle.GetStringSelection())
        self.plan.set_dose_algorithm(self.drop_dose_alg.GetStringSelection())
        self.plan.set_bio_algorithm(self.drop_bio_alg.GetStringSelection())
        self.plan.set_opt_algorithm(self.drop_opt_alg.GetStringSelection())

        self.plan.set_out_phys_dose(self.check_phys_dose.GetValue())
        self.plan.set_out_bio_dose(self.check_bio_dose.GetValue())
        self.plan.set_out_dose_mean_let(self.check_dose_mean_let.GetValue())
        self.plan.set_out_field(self.check_field.GetValue())

        self.plan.set_ddd_folder(self.txt_ddd.GetValue())
        self.plan.set_spc_folder(self.txt_ddd.GetValue())
        self.plan.set_sis_file(self.txt_sis.GetValue())

        self.Close()

    def close(self, evt):
        self.Close()