Exemple #1
0
    def __init__(self, progress_callback, interrupt_flag, patient_files,
                 input_path):
        """
        Class initialiser function.
        :param progress_callback: A signal that receives the current
                                  progress of the loading.
        :param interrupt_flag: A threading.Event() object that tells the
                               function to stop loading.
        :param patient_files: List of patient files.
        :param output_path: Path of the input CSV file.
        """
        # Call the parent class
        super(BatchProcessCSV2ClinicalDataSR,
              self).__init__(progress_callback, interrupt_flag, patient_files)

        # Set class variables
        self.patient_dict_container = PatientDictContainer()
        self.required_classes = ['ct', 'rtdose']
        self.required_classes_2 = ['pet', 'rtdose']

        # Only need one of either ct or pet (and rtdose)
        self.ready = False
        ready = self.load_images(patient_files, self.required_classes)
        if ready:
            self.ready = True
        else:
            self.ready = \
                self.load_images(patient_files, self.required_classes_2)
        self.input_path = input_path
Exemple #2
0
    def onSaveClicked(self):
        """ Save the new ROI """
        # Get the name of the new ROI
        new_roi_name = self.new_roi_name_line_edit.text()

        # If the new ROI hasn't been drawn, draw the new ROI. Then if the new
        # ROI is drawn successfully, proceed to save the new ROI.
        if self.new_ROI_contours is None:
            if not self.onDrawButtonClicked():
                return

        # Get a dict to convert SOPInstanceUID to slice id
        slice_ids_dict = get_dict_slice_to_uid(PatientDictContainer())

        # Transform new_ROI_contours to a list of roi information
        rois_to_save = {}

        for uid, contour_sequence in self.new_ROI_contours.items():
            slider_id = slice_ids_dict[uid]
            location = self.patient_dict_container.filepaths[slider_id]
            ds = pydicom.dcmread(location)
            slice_info = {'coords': contour_sequence, 'ds': ds}
            rois_to_save[slider_id] = slice_info

        roi_list = ROI.convert_hull_list_to_contours_data(
            rois_to_save, self.patient_dict_container)

        connectSaveROIProgress(self, roi_list, self.dataset_rtss, new_roi_name,
                               self.roi_saved)
 def cleanup(self):
     patient_dict_container = PatientDictContainer()
     patient_dict_container.clear()
     # Close 3d vtk widget
     self.three_dimension_view.close()
     self.cleanup_image_fusion()
     self.cleanup_pt_ct_viewer()
Exemple #4
0
def test_save_radiomics_data():
    """
    Test for saving pyradiomics data to a DICOM SR file.
    """
    # Get test data files
    # Load test DICOM files
    desired_path = Path.cwd().joinpath('test', 'testdata')

    # list of DICOM test files
    selected_files = find_DICOM_files(desired_path)
    # file path of DICOM files
    file_path = os.path.dirname(os.path.commonprefix(selected_files))
    read_data_dict, file_names_dict = \
        ImageLoading.get_datasets(selected_files)

    # Create patient dict container object
    patient_dict_container = PatientDictContainer()
    patient_dict_container.clear()
    patient_dict_container.set_initial_values(file_path, read_data_dict,
                                              file_names_dict)

    file_path = patient_dict_container.path
    file_path = Path(file_path).joinpath("PyRadiomics-SR.dcm")
    ds = patient_dict_container.dataset[0]
    dicom_sr = DICOMStructuredReport.generate_dicom_sr(file_path, ds, "text",
                                                       "PYRADIOMICS")
    dicom_sr.save_as(file_path)

    # Assert that the new SR exists
    assert os.path.isfile(file_path)

    # Delete the created DICOM SR
    os.remove(file_path)
def test_create_roi():
    rt_ss = dataset.Dataset()

    rt_ss.StructureSetROISequence = []
    rt_ss.StructureSetROISequence.append(dataset.Dataset())
    rt_ss.StructureSetROISequence[0].ReferencedFrameOfReferenceUID = "1.2.3"
    rt_ss.StructureSetROISequence[0].ROINumber = "1"

    rt_ss.ROIContourSequence = []

    rt_ss.RTROIObservationsSequence = []

    roi_name = "NewTestROI"
    roi_coordinates = [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0,
                       0]  # a closed right triangle
    image_ds = dataset.Dataset()
    image_ds.SOPClassUID = "1.2.840.10008.5.1.4.1.1.2"
    image_ds.SOPInstanceUID = "1.2.3.4.5.6.7.8.9"
    patient_dict_container = PatientDictContainer()
    # container has to be initialised with kwargs content for the get/set to not fail for lack of an
    # "additional_parameters" dict.
    patient_dict_container.set_initial_values(None,
                                              None,
                                              None,
                                              blah="blah",
                                              rois={})
    if patient_dict_container.get("rois") is not None:
        print("rois are present in patient dict container")
    updated_rtss = create_roi(rt_ss, roi_name, roi_coordinates, image_ds)
    first_contour = updated_rtss.ROIContourSequence[0].ContourSequence[0]
    assert (first_contour.ContourImageSequence[0].ReferencedSOPClassUID ==
            image_ds.SOPClassUID)
    assert (first_contour.ContourGeometricType == "CLOSED_PLANAR")
    assert (rt_ss.RTROIObservationsSequence[0].RTROIInterpretedType == "ORGAN")
    def batch_iso2roi_handler(self, interrupt_flag, progress_callback,
                              patient):
        """
        Handles creating, starting, and processing the results of batch
        ISO2ROI.
        :param interrupt_flag: A threading.Event() object that tells the
                               function to stop loading.
        :param progress_callback: A signal that receives the current
                                  progress of the loading.
        :param patient: The patient to perform this process on.
        """
        # Get current patient files
        cur_patient_files = \
            BatchProcessingController.get_patient_files(patient)

        # Create and start process
        process = BatchProcessISO2ROI(progress_callback, interrupt_flag,
                                      cur_patient_files)
        success = process.start()

        # Add rtss to patient in case it is needed in future
        # processes
        if success:
            if PatientDictContainer().get("rtss_modified"):
                self.update_rtss(patient)
            reason = "SUCCESS"
        else:
            reason = process.summary

        # Append process summary
        if patient not in self.batch_summary[0].keys():
            self.batch_summary[0][patient] = {}
        self.batch_summary[0][patient]["iso2roi"] = reason
        progress_callback.emit(("Completed ISO2ROI", 100))
Exemple #7
0
    def populate_table(self):
        """
        Populates the table with data from the DICOM-SR file, if it
        exists.
        """
        # Attempt to get clinical data dataset
        patient_dict_container = PatientDictContainer()
        try:
            clinical_data = patient_dict_container.dataset['sr-cd']

            # Get text from clinical data dataset
            text = clinical_data.ContentSequence[0].TextValue

            # Split text into dictionary
            text_data = text.splitlines()
            for row in text_data:
                key, value = row.split(":")
                self.data_dict[key] = value
        except KeyError:
            # See if data has been imported
            if self.data_dict:
                pass
            else:
                return

        # Populate table with loaded values
        for i, key in enumerate(self.data_dict):
            attrib = QtWidgets.QTableWidgetItem(key)
            value = QtWidgets.QTableWidgetItem(self.data_dict[key])
            self.table_cd.insertRow(i)
            self.table_cd.setItem(i, 0, attrib)
            self.table_cd.setItem(i, 1, value)
        self.table_populated = True
Exemple #8
0
    def __init__(self):
        # Load test DICOM files
        desired_path = Path.cwd().joinpath('test', 'testdata')
        selected_files = find_DICOM_files(desired_path)  # list of DICOM test files
        file_path = os.path.dirname(os.path.commonprefix(selected_files))  # file path of DICOM files
        read_data_dict, file_names_dict = ImageLoading.get_datasets(selected_files)

        # Create patient dict container object
        patient_dict_container = PatientDictContainer()
        patient_dict_container.clear()
        patient_dict_container.set_initial_values(file_path, read_data_dict, file_names_dict)

        # Set additional attributes in patient dict container (otherwise program will crash and test will fail)
        if "rtss" in file_names_dict:
            dataset_rtss = dcmread(file_names_dict['rtss'])
            self.rois = ImageLoading.get_roi_info(dataset_rtss)
            dict_raw_contour_data, dict_numpoints = ImageLoading.get_raw_contour_data(dataset_rtss)
            dict_pixluts = ImageLoading.get_pixluts(read_data_dict)

            patient_dict_container.set("rois", self.rois)
            patient_dict_container.set("raw_contour", dict_raw_contour_data)
            patient_dict_container.set("num_points", dict_numpoints)
            patient_dict_container.set("pixluts", dict_pixluts)

        # Open the main window
        self.main_window = MainWindow()
Exemple #9
0
    def __init__(self):
        # Load test DICOM files and set path variable
        path = Path.cwd().joinpath('test', 'testdata')
        files = get_dicom_files(path)  # list of DICOM test files
        file_path = os.path.dirname(os.path.commonprefix(files))
        read_data_dict, file_names_dict = ImageLoading.get_datasets(files)

        # Create patient dict container object
        patient_dict_container = PatientDictContainer()
        patient_dict_container.clear()
        patient_dict_container.set_initial_values(file_path, read_data_dict,
                                                  file_names_dict)

        # Set additional attributes in patient dict container
        # This prevents crashes
        if "rtss" in file_names_dict:
            dataset_rtss = dcmread(file_names_dict['rtss'])
            self.rois = ImageLoading.get_roi_info(dataset_rtss)
            patient_dict_container.set("rois", self.rois)

        # Open the main window
        self.main_window = MainWindow()
        self.main_window.right_panel.setCurrentWidget(
            self.main_window.dicom_tree)
        self.dicom_tree = self.main_window.dicom_tree
Exemple #10
0
    def on_loaded_suv2roi(self):
        """
        Called when progress bar has finished. Closes the progress
        window and refreshes the main screen.
        """
        if self.suv2roi.suv2roi_status:
            patient_dict_container = PatientDictContainer()
            self.structures_tab.fixed_container_structure_modified((
                patient_dict_container.get('dataset_rtss'), {"draw": None}))
        else:
            # Alert user that SUV2ROI failed and for what reason
            if self.suv2roi.failure_reason == "UNIT":
                failure_reason = \
                    "PET units are not Bq/mL. OnkoDICOM can currently only\n" \
                    "perform SUV2ROI on PET images stored in these units."
            elif self.suv2roi.failure_reason == "DECY":
                failure_reason = \
                    "PET is not decay corrected. OnkoDICOM can currently " \
                    "only\nperform SUV2ROI on PET images that are decay " \
                    "corrected."
            else:
                failure_reason = "The SUV2ROI process has failed."
            button_reply = \
                QtWidgets.QMessageBox(
                    QtWidgets.QMessageBox.Icon.Warning,
                    "SUV2ROI Failed",
                    failure_reason,
                    QtWidgets.QMessageBox.StandardButton.Ok, self)
            button_reply.button(
                QtWidgets.QMessageBox.StandardButton.Ok).setStyleSheet(
                self.stylesheet)
            button_reply.exec_()

        # Close progress window
        self.suv2roi_progress_window.close()
Exemple #11
0
    def __init__(self):
        QtWidgets.QWidget.__init__(self)
        self.patient_dict_container = PatientDictContainer()
        self.rx_dose_in_cgray = self.patient_dict_container.get(
            "rx_dose_in_cgray")
        self.color_dict = self.init_color_isod()
        self.color_squares = self.init_color_squares()
        self.checkboxes = self.init_checkboxes()

        # Create and initialise ISO2ROI button and layout
        self.iso2roi_button = QtWidgets.QPushButton()
        self.iso2roi_button.setText("Convert Isodoses to ROIs")
        self.iso2roi_button.clicked.connect(self.iso2roi_button_clicked)

        self.iso2roi_layout = QtWidgets.QHBoxLayout()
        self.iso2roi_layout.setContentsMargins(0, 0, 0, 0)
        self.iso2roi_layout.addWidget(self.iso2roi_button)

        self.isodose_tab_layout = QtWidgets.QVBoxLayout()
        self.isodose_tab_layout.setAlignment(QtCore.Qt.AlignTop
                                             | QtCore.Qt.AlignTop)
        self.isodose_tab_layout.setSpacing(0)
        self.init_layout()
        self.iso2roi = ISO2ROI()

        # Add button to tab
        self.isodose_tab_layout.addStretch()
        self.isodose_tab_layout.addLayout(self.iso2roi_layout)

        self.setLayout(self.isodose_tab_layout)
        self.progress_window = ProgressWindow(
            self, QtCore.Qt.WindowTitleHint | QtCore.Qt.WindowCloseButtonHint)
        self.progress_window.signal_loaded.connect(self.on_loaded_iso2roi)
Exemple #12
0
 def save_rtss(cls):
     """
     Saves the RT Struct.
     """
     patient_dict_container = PatientDictContainer()
     rtss_directory = Path(patient_dict_container.get("file_rtss"))
     patient_dict_container.get("dataset_rtss").save_as(rtss_directory)
Exemple #13
0
    def save_clinical_data(self):
        """
        Saves clinical data to a DICOM-SR file. Overwrites any existing
        clinical data SR files in the dataset.
        """
        # Only save if there is at least one row in the table
        if self.table_cd.rowCount() <= 0:
            return

        # Create string from clinical data dictionary
        text = ""
        for key in self.data_dict:
            text += str(key) + ": " + str(self.data_dict[key]) + "\n"

        # Create and save DICOM SR file
        patient_dict_container = PatientDictContainer()
        file_path = patient_dict_container.path
        file_path = Path(file_path).joinpath("Clinical-Data-SR.dcm")
        ds = patient_dict_container.dataset[0]
        dicom_sr = DICOMStructuredReport.generate_dicom_sr(
            file_path, ds, text, "CLINICAL-DATA")
        dicom_sr.save_as(file_path)

        # Update patient dict container
        patient_dict_container.dataset['sr-cd'] = dicom_sr
        patient_dict_container.filepaths['sr-cd'] = file_path
Exemple #14
0
    def __init__(self, *args, **kwargs):
        super(CalculateDVHProgressWindow, self).__init__(*args, **kwargs)
        layout = QtWidgets.QVBoxLayout()
        text = QtWidgets.QLabel(
            "Calculating DVHs... (This may take several minutes)")
        layout.addWidget(text)
        self.setWindowTitle("Please wait...")
        self.setLayout(layout)

        self.threadpool = QtCore.QThreadPool()
        self.patient_dict_container = PatientDictContainer()

        dataset_rtss = self.patient_dict_container.dataset["rtss"]
        dataset_rtdose = self.patient_dict_container.dataset["rtdose"]
        rois = self.patient_dict_container.get("rois")

        dict_thickness = ImageLoading.get_thickness_dict(
            dataset_rtss, self.patient_dict_container.dataset)

        interrupt_flag = threading.Event()
        fork_safe_platforms = ['Linux']
        if platform.system() in fork_safe_platforms:
            worker = Worker(ImageLoading.multi_calc_dvh, dataset_rtss,
                            dataset_rtdose, rois, dict_thickness)
        else:
            worker = Worker(ImageLoading.calc_dvhs, dataset_rtss,
                            dataset_rtdose, rois, dict_thickness,
                            interrupt_flag)

        worker.signals.result.connect(self.dvh_calculated)

        self.threadpool.start(worker)
Exemple #15
0
    def __init__(self, roi_color=None, iso_color=None):
        QtWidgets.QWidget.__init__(self)
        self.patient_dict_container = PatientDictContainer()
        self.iso_color = iso_color
        self.zoom = 1
        self.current_slice_number = None

        self.dicom_view_layout = QtWidgets.QHBoxLayout()

        # Create components
        self.slider = QtWidgets.QSlider(QtCore.Qt.Vertical)
        self.init_slider()
        self.view = QtWidgets.QGraphicsView()
        self.init_view()
        self.scene = QtWidgets.QGraphicsScene()

        # Set layout
        self.dicom_view_layout.addWidget(self.view)
        self.dicom_view_layout.addWidget(self.slider)
        self.setLayout(self.dicom_view_layout)

        # Init metadata widgets
        self.metadata_layout = QtWidgets.QVBoxLayout(self.view)
        self.label_image_id = QtWidgets.QLabel()
        self.label_image_pos = QtWidgets.QLabel()
        self.label_wl = QtWidgets.QLabel()
        self.label_image_size = QtWidgets.QLabel()
        self.label_zoom = QtWidgets.QLabel()
        self.label_patient_pos = QtWidgets.QLabel()
        self.init_metadata()

        self.update_view()
Exemple #16
0
    def __init__(self):
        QtWidgets.QWidget.__init__(self)
        self.patient_dict_container = PatientDictContainer()
        self.dvh_calculated = self.patient_dict_container.has_attribute(
            "raw_dvh")
        self.rt_dose = self.patient_dict_container.dataset['rtdose']

        self.raw_dvh = None
        self.dvh_x_y = None
        self.plot = None

        self.selected_rois = self.patient_dict_container.get("selected_rois")

        self.dvh_tab_layout = QtWidgets.QVBoxLayout()

        try:
            # Import the DVH from RT Dose
            self.import_rtdose()
        except (AttributeError, KeyError):
            # Construct the layout based on whether or not the DVH has
            # already been calculated.
            # TODO: convert to logging
            print("DVH data not in RT Dose.")
            if self.dvh_calculated:
                self.init_layout_dvh()
            else:
                self.init_layout_no_dvh()

        self.setLayout(self.dvh_tab_layout)
Exemple #17
0
    def __init__(self):
        # Load test DICOM files
        desired_path = Path.cwd().joinpath('test', 'pet-testdata')

        # list of DICOM test files
        selected_files = find_dicom_files(desired_path)
        # file path of DICOM files
        file_path = os.path.dirname(os.path.commonprefix(selected_files))
        read_data_dict, file_names_dict = \
            ImageLoading.get_datasets(selected_files)

        # Create patient dict container object
        self.patient_dict_container = PatientDictContainer()
        self.patient_dict_container.clear()
        self.patient_dict_container.set_initial_values \
            (file_path, read_data_dict, file_names_dict)

        # Create variables to be initialised later
        self.dicom_files = None
        self.suv_data = []

        # Create SUV2ROI object
        self.suv2roi = SUV2ROI()
        # Set patient weight. Not actual weight, just for testing
        # purposes.
        self.suv2roi.patient_weight = 70000
Exemple #18
0
    def update_ui(self):
        # Instantiate a local new PatientDictContainer
        patient_dict_container = PatientDictContainer()
        patient = patient_dict_container.get("basic_info")

        # Compare local patient with previous instance of ImageFusion
        if self.patient_id != patient['id']:
            self.update_patient()
Exemple #19
0
    def update_patient(self):
        self.clear_checked_leaves()
        self.patient_dict_container = PatientDictContainer()
        self.patient = self.patient_dict_container.get("basic_info")
        self.patient_id = self.patient['id']

        dataset = self.patient_dict_container.dataset[0]
        self.patient_current_image_series_uid = \
            dataset.get("SeriesInstanceUID")
Exemple #20
0
 def update_ui(self, moving=False):
     """
     Update the UI of Structure Tab when a new patient is opened
     """
     self.patient_dict_container = PatientDictContainer()
     self.rois = self.patient_dict_container.get("rois")
     self.color_dict = self.init_color_roi(self.patient_dict_container)
     self.patient_dict_container.set("roi_color_dict", self.color_dict)
     if hasattr(self, "modified_indicator_widget"):
         self.modified_indicator_widget.setParent(None)
     self.update_content()
Exemple #21
0
def get_fused_window(level, window):
    """
    Apply windowing on the fixed and moving (linear-registered) images.
    
    Args:
        level(int): the level (midpoint) of windowing
        window(any): the window (range) of windowing
    
    Return:
        color_axial (QtGui.QPixmap): pixmap of the registered image from axial 
        view
        color_sagittal (QtGui.QPixmap): pixmap of the registered image from 
        sagittal view
        color_coronal (QtGui.QPixmap): pixmap of the registered image from 
        coronal view
        tfm (sitk.CompositeTransform): transformation object containing data 
        that is a product from linear_registration
    """

    patient_dict_container = PatientDictContainer()
    old_images = patient_dict_container.get("sitk_original")
    fused_image = patient_dict_container.get("fused_images")
    tfm = fused_image[1]
    array = sitk.GetArrayFromImage(old_images).shape

    axial_slice_count = array[0]
    coronal_slice_count = array[1]
    sagittal_slice_count = array[1]

    sp_plane, _, sp_slice = old_images.GetSpacing()
    asp = (1.0 * sp_slice) / sp_plane

    color_axial = {}
    color_sagittal = {}
    color_coronal = {}

    windowing = (int(level - CT_RESCALE_INTERCEPT), int(window))

    for i in range(axial_slice_count):
        color_axial[i] = \
            get_fused_pixmap(old_images, fused_image[0], asp, i, "axial",
                             windowing)

    for i in range(sagittal_slice_count):
        color_sagittal[i] = \
            get_fused_pixmap(old_images, fused_image[0], asp, i, "sagittal",
                             windowing)

    for i in range(coronal_slice_count):
        color_coronal[i] = \
            get_fused_pixmap(old_images, fused_image[0], asp, i, "coronal",
                             windowing)

    return color_axial, color_sagittal, color_coronal, tfm
    def update_rtss(self, patient):
        """
        Updates the patient dict container with the newly created RTSS (if a
        process generates one), so it can be used by future processes.
        :param patient: The patient with the newly-created RTSS.
        """
        # Get new RTSS
        rtss = PatientDictContainer().dataset['rtss']

        # Create a series and image from the RTSS
        rtss_series = Series(rtss.SeriesInstanceUID)
        rtss_series.series_description = rtss.get("SeriesDescription")
        rtss_image = Image(PatientDictContainer().filepaths['rtss'],
                           rtss.SOPInstanceUID, rtss.SOPClassUID,
                           rtss.Modality)
        rtss_series.add_image(rtss_image)

        # Add the new study to the patient
        patient.studies[rtss.StudyInstanceUID].add_series(rtss_series)

        # Update the patient dict container
        PatientDictContainer().set("rtss_modified", False)
Exemple #23
0
def read_images_for_fusion(level=0, window=0):
    """
    Performs initial image fusion, this is by converting the old and
    new images for transformations into SITK object. Images are co-registered 
    using SITK library. Images and SITK.CompositeTransformation objects are 
    added to the patient dataset.
    
    Args:
        level(int): midpoint of window
        window(Any): range of values, should at least contain low bound and 
        high bound
    """
    patient_dict_container = PatientDictContainer()
    moving_dict_container = MovingDictContainer()
    if level == 0 or window == 0:
        level = patient_dict_container.get("level")
        window = patient_dict_container.get("window")

    amount = len(patient_dict_container.filepaths)
    orig_fusion_list = []

    for i in range(amount):
        try:
            orig_fusion_list.append(patient_dict_container.filepaths[i])
        except KeyError:
            continue

    orig_image = sitk.ReadImage(orig_fusion_list)
    patient_dict_container.set("sitk_original", orig_image)

    amount = len(moving_dict_container.filepaths)
    new_fusion_list = []

    for i in range(amount):
        try:
            new_fusion_list.append(moving_dict_container.filepaths[i])
        except KeyError:
            continue

    new_image = sitk.ReadImage(new_fusion_list)
    moving_dict_container.set("sitk_moving", new_image)

    create_fused_model(orig_image, new_image)
    color_axial, color_sagittal, color_coronal, tfm = \
        get_fused_window(level, window)

    patient_dict_container.set("color_axial", color_axial)
    patient_dict_container.set("color_sagittal", color_sagittal)
    patient_dict_container.set("color_coronal", color_coronal)
    moving_dict_container.set("tfm", tfm)
Exemple #24
0
    def __init__(self):
        QtWidgets.QWidget.__init__(self)
        self.patient_dict_container = PatientDictContainer()
        self.rx_dose_in_cgray = self.patient_dict_container.get("rx_dose_in_cgray")
        self.color_dict = self.init_color_isod()
        self.color_squares = self.init_color_squares()
        self.checkboxes = self.init_checkboxes()

        self.isodose_tab_layout = QtWidgets.QVBoxLayout()
        self.isodose_tab_layout.setAlignment(QtCore.Qt.AlignTop)
        self.isodose_tab_layout.setSpacing(0)
        self.init_layout()

        self.setLayout(self.isodose_tab_layout)
Exemple #25
0
    def perform_suv2roi(self):
        """
        Performs the SUV2ROI process.
        """
        # Get patient weight - needs to run first as GUI cannot run in
        # threads, like the ProgressBar
        patient_dict_container = PatientDictContainer()
        dataset = patient_dict_container.dataset[0]
        self.suv2roi.get_patient_weight(dataset)
        if self.suv2roi.patient_weight is None:
            return

        # Start the SUV2ROI process
        self.suv2roi_progress_window.start(self.suv2roi.start_conversion)
Exemple #26
0
    def __init__(self, action_handler: ActionHandler):
        QToolBar.__init__(self)
        self.action_handler = action_handler
        self.patient_dict_container = PatientDictContainer()
        self.setCursor(QCursor(Qt.PointingHandCursor))
        self.setMovable(False)
        self.setFloatable(False)
        self.setContextMenuPolicy(Qt.PreventContextMenu)

        # Drop-down list for Windowing button on toolbar
        self.button_windowing = QToolButton()
        self.button_windowing.setMenu(self.action_handler.menu_windowing)
        self.button_windowing.setPopupMode(QToolButton.InstantPopup)
        self.button_windowing.setIcon(self.action_handler.icon_windowing)

        # Drop-down list for Export button on toolbar
        self.button_export = QToolButton()
        self.button_export.setMenu(self.action_handler.menu_export)
        self.button_export.setPopupMode(QToolButton.InstantPopup)
        self.button_export.setIcon(self.action_handler.icon_export)

        # Spacer for the toolbar
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        spacer.setFocusPolicy(Qt.NoFocus)

        # Add actions to toolbar
        self.addAction(self.action_handler.action_open)
        self.addSeparator()
        self.addAction(self.action_handler.action_zoom_out)
        self.addAction(self.action_handler.action_zoom_in)
        self.addSeparator()
        self.addWidget(self.button_windowing)
        self.addSeparator()
        self.addAction(self.action_handler.action_transect)
        self.addSeparator()
        self.addAction(self.action_handler.action_one_view)
        self.addAction(self.action_handler.action_four_views)
        self.addAction(self.action_handler.action_show_cut_lines)
        self.addSeparator()
        self.addAction(self.action_handler.action_image_fusion)
        self.addSeparator()
        self.addAction(self.action_handler.action_add_ons)
        self.addWidget(spacer)
        self.addWidget(self.button_export)
        self.addAction(self.action_handler.action_save_as_anonymous)
        if self.patient_dict_container.has_modality('rtss'):
            self.addAction(self.action_handler.action_save_structure)
Exemple #27
0
    def __init__(self):
        self.dvh_data = None

        # Load test DICOM files
        desired_path = Path.cwd().joinpath('test', 'testdata')
        selected_files = find_DICOM_files(desired_path)
        file_path = os.path.dirname(os.path.commonprefix(selected_files))
        read_data_dict, file_names_dict = \
            ImageLoading.get_datasets(selected_files)

        # Create patient dict container object
        self.patient_dict_container = PatientDictContainer()
        self.patient_dict_container.clear()
        self.patient_dict_container.set_initial_values(file_path,
                                                       read_data_dict,
                                                       file_names_dict)
Exemple #28
0
def create_fused_model(old_images, new_image):
    """
    Performs the image fusion and stores fusion information.
    
    Args:
        old_images(sitk): Image set from Primary/Fixed Image
        new_image(sitk): Image set from the Secondary/Moving Image
    """
    patient_dict_container = PatientDictContainer()
    fused_image = register_images(old_images, new_image)
    patient_dict_container.set("fused_images", fused_image)

    if fused_image[2]:
        combined_affine = convert_composite_to_affine_transform(fused_image[1])
        affine_matrix = convert_combined_affine_to_matrix(combined_affine)
        write_transform_to_dcm(affine_matrix)
Exemple #29
0
    def create_new_rtstruct(cls, progress_callback):
        """
        Generates a new RTSS and edits the patient dict container. Used
        for batch processing.
        """
        # Get common directory
        patient_dict_container = PatientDictContainer()
        file_path = patient_dict_container.filepaths.values()
        file_path = Path(os.path.commonpath(file_path))

        # Get new RT Struct file path
        file_path = str(file_path.joinpath("rtss.dcm"))

        # Create RT Struct file
        progress_callback.emit(("Generating RT Structure Set", 60))
        ct_uid_list = ImageLoading.get_image_uid_list(
            patient_dict_container.dataset)
        ds = ROI.create_initial_rtss_from_ct(patient_dict_container.dataset[0],
                                             file_path, ct_uid_list)
        ds.save_as(file_path)

        # Add RT Struct file path to patient dict container
        patient_dict_container.filepaths['rtss'] = file_path
        filepaths = patient_dict_container.filepaths

        # Add RT Struct dataset to patient dict container
        patient_dict_container.dataset['rtss'] = ds
        dataset = patient_dict_container.dataset

        # Set some patient dict container attributes
        patient_dict_container.set("file_rtss", filepaths['rtss'])
        patient_dict_container.set("dataset_rtss", dataset['rtss'])

        dicom_tree_rtss = DicomTree(filepaths['rtss'])
        patient_dict_container.set("dict_dicom_tree_rtss",
                                   dicom_tree_rtss.dict)

        dict_pixluts = ImageLoading.get_pixluts(patient_dict_container.dataset)
        patient_dict_container.set("pixluts", dict_pixluts)

        rois = ImageLoading.get_roi_info(ds)
        patient_dict_container.set("rois", rois)

        patient_dict_container.set("selected_rois", [])
        patient_dict_container.set("dict_polygons_axial", {})

        patient_dict_container.set("rtss_modified", True)
Exemple #30
0
def dvh2rtdose(dict_dvh):
    """
    Export dvh data to RT DOSE file.
    :param dict_dvh: A dictionary of DVH {ROINumber: DVH}
    :param patient_id: Patient Identifier
    """
    # Create DVH sequence
    dvh_sequence = Sequence([])

    # Add DVHs to the sequence
    for ds in dict_dvh:
        # Create new DVH dataset
        new_ds = Dataset()

        # Add attributes
        new_ds.add_new(Tag("DVHType"), "CS", dict_dvh[ds].dvh_type.upper())
        new_ds.add_new(Tag("DoseUnits"), "CS", dict_dvh[ds].dose_units.upper())
        new_ds.add_new(Tag("DoseType"), "CS", "PHYSICAL")
        new_ds.add_new(Tag("DVHDoseScaling"), "DS", "1.0")
        new_ds.add_new(Tag("DVHVolumeUnits"), "CS",
                       dict_dvh[ds].volume_units.upper())
        new_ds.add_new(Tag("DVHNumberOfBins"), "IS", len(dict_dvh[ds].bins))

        # Calculate and add DVH data
        dvh_data = []
        for i in range(len(dict_dvh[ds].counts)):
            dvh_data.append(str(dict_dvh[ds].bins[1]))
            dvh_data.append(str(dict_dvh[ds].counts[i]))
        new_ds.add_new(Tag("DVHData"), "DS", dvh_data)

        # Reference ROI sequence dataset/sequence
        referenced_roi_sequence = Dataset()
        referenced_roi_sequence.add_new(Tag("DVHROIContributionType"), "CS",
                                        "INCLUDED")
        referenced_roi_sequence.add_new(Tag("ReferencedROINumber"), "IS", ds)
        new_ds.add_new(Tag("DVHReferencedROISequence"), "SQ",
                       Sequence([referenced_roi_sequence]))

        # Add new DVH dataset to DVH sequences
        dvh_sequence.append(new_ds)

    # Save new RT DOSE
    patient_dict_container = PatientDictContainer()
    patient_dict_container.dataset['rtdose'].DVHSequence = dvh_sequence

    path = patient_dict_container.filepaths['rtdose']
    patient_dict_container.dataset['rtdose'].save_as(path)