Esempio n. 1
0
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")
Esempio n. 2
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()
Esempio n. 3
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
class TestClinicalDataView:
    """
    Class to set up variables required for testing the Clinical Data
    view.
    """
    __test__ = False

    def __init__(self):
        # 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
        self.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(self.file_path,
                                                       read_data_dict,
                                                       file_names_dict)

        self.file_path = self.patient_dict_container.path
        self.file_path = Path(self.file_path).joinpath("Clinical-Data-SR.dcm")

        # Test data to write
        self.data = [['123456789', 'Jim', 'Jimson']]
Esempio n. 5
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 __init__(self):
        # Load test DICOM files
        if platform.system() == "Windows":
            desired_path = "\\testdata\\DICOM-RT-TEST"
        elif platform.system() == "Linux" or platform.system() == "Darwin":
            desired_path = "/testdata/DICOM-RT-TEST"

        desired_path = os.path.dirname(
            os.path.realpath(__file__)) + desired_path

        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()
        self.main_window.show()

        self.dicom_view = self.main_window.dicom_view
        self.new_polygons = {}
        slider_id = self.dicom_view.slider.value()
        self.curr_slice = self.dicom_view.patient_dict_container.get(
            "dict_uid")[slider_id]
Esempio n. 7
0
def test_add_to_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.StructureSetROISequence[0].ROIName = "NewTestROI"

    rt_ss.ROIContourSequence = []

    rt_ss.RTROIObservationsSequence = []

    roi_name = "NewTestROI"
    roi_coordinates = [0, 0, 0, 0, 1, 0, 1, 0, 0]  # a 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,
                              [{'coords': roi_coordinates, 'ds': image_ds}])
    # clearly the above is an opportunity to factor out to a fixture or similar
    rtss_with_added_roi = add_to_roi(updated_rtss, roi_name,
                                     roi_coordinates, image_ds)
    first_contour = rtss_with_added_roi.ROIContourSequence[0].\
        ContourSequence[0]
    second_contour = rtss_with_added_roi.ROIContourSequence[0].\
        ContourSequence[1]
    assert (
        second_contour
        .ContourImageSequence[0]
        .ReferencedSOPClassUID
        == image_ds.SOPClassUID
    )
    assert(first_contour.ContourGeometricType == "OPEN_PLANAR")
    assert (second_contour.ContourGeometricType == "OPEN_PLANAR")
Esempio n. 8
0
class TestDvh2RtDose:
    """
    This class is to set up data and variables needed for the DVH2RTDOSE
    functionality.
    """

    __test__ = False

    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)
Esempio n. 9
0
    def load(self, interrupt_flag, progress_callback):
        """
        :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.
        :return: PatientDictContainer object containing all values related to the loaded DICOM files.
        """
        progress_callback.emit(("Creating datasets...", 0))
        try:
            path = os.path.dirname(os.path.commonprefix(self.selected_files))  # Gets the common root folder.
            read_data_dict, file_names_dict = ImageLoading.get_datasets(self.selected_files)
        except ImageLoading.NotAllowedClassError:
            raise ImageLoading.NotAllowedClassError

        # Populate the initial values in the PatientDictContainer singleton.
        patient_dict_container = PatientDictContainer()
        patient_dict_container.clear()
        patient_dict_container.set_initial_values(path, read_data_dict, file_names_dict)

        # As there is no way to interrupt a QRunnable, this method must check after every step whether or not the
        # interrupt flag has been set, in which case it will interrupt this method after the currently processing
        # function has finished running. It's not very pretty, and the thread will still run some functions for, in some
        # cases, up to a couple seconds after the close button on the Progress Window has been clicked, however it's
        # the best solution I could come up with. If you have a cleaner alternative, please make your contribution.
        if interrupt_flag.is_set():
            print("stopped")
            return False

        if 'rtss' in file_names_dict and 'rtdose' in file_names_dict:
            self.parent_window.signal_advise_calc_dvh.connect(self.update_calc_dvh)
            self.signal_request_calc_dvh.emit()

            while not self.advised_calc_dvh:
                pass

        if 'rtss' in file_names_dict:
            dataset_rtss = dcmread(file_names_dict['rtss'])

            progress_callback.emit(("Getting ROI info...", 10))
            rois = ImageLoading.get_roi_info(dataset_rtss)

            if interrupt_flag.is_set():  # Stop loading.
                print("stopped")
                return False

            progress_callback.emit(("Getting contour data...", 30))
            dict_raw_contour_data, dict_numpoints = ImageLoading.get_raw_contour_data(dataset_rtss)

            # Determine which ROIs are one slice thick
            dict_thickness = ImageLoading.get_thickness_dict(dataset_rtss, read_data_dict)

            if interrupt_flag.is_set():  # Stop loading.
                print("stopped")
                return False

            progress_callback.emit(("Getting pixel LUTs...", 50))
            dict_pixluts = ImageLoading.get_pixluts(read_data_dict)

            if interrupt_flag.is_set():  # Stop loading.
                print("stopped")
                return False

            # Add RTSS values to PatientDictContainer
            patient_dict_container.set("rois", 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)

            if 'rtdose' in file_names_dict and self.calc_dvh:
                dataset_rtdose = dcmread(file_names_dict['rtdose'])

                # Spawn-based platforms (i.e Windows and MacOS) have a large overhead when creating a new process, which
                # ends up making multiprocessing on these platforms more expensive than linear calculation. As such,
                # multiprocessing is only available on Linux until a better solution is found.
                fork_safe_platforms = ['Linux']
                if platform.system() in fork_safe_platforms:
                    progress_callback.emit(("Calculating DVHs...", 60))
                    raw_dvh = ImageLoading.multi_calc_dvh(dataset_rtss, dataset_rtdose, rois, dict_thickness)
                else:
                    progress_callback.emit(("Calculating DVHs... (This may take a while)", 60))
                    raw_dvh = ImageLoading.calc_dvhs(dataset_rtss, dataset_rtdose, rois, dict_thickness, interrupt_flag)

                if interrupt_flag.is_set():  # Stop loading.
                    print("stopped")
                    return False

                progress_callback.emit(("Converging to zero...", 80))
                dvh_x_y = ImageLoading.converge_to_0_dvh(raw_dvh)

                if interrupt_flag.is_set():  # Stop loading.
                    print("stopped")
                    return False

                # Add DVH values to PatientDictContainer
                patient_dict_container.set("raw_dvh", raw_dvh)
                patient_dict_container.set("dvh_x_y", dvh_x_y)
                patient_dict_container.set("dvh_outdated", False)

                return True
            else:
                return True

        return True
Esempio n. 10
0
    def load_images(cls, patient_files, required_classes):
        """
        Loads required datasets for the selected patient.
        :param patient_files: dictionary of classes and patient files.
        :param required_classes: list of classes required for the
                                 selected/current process.
        :return: True if all required datasets found, false otherwise.
        """
        files = []
        found_classes = set()

        # Loop through each item in patient_files
        for key, value in patient_files.items():
            # If the item is an allowed class
            if key in cls.allowed_classes:
                for i in range(len(value)):
                    # Add item's files to the files list
                    files.extend(value[i].get_files())

                # Get the modality name
                modality_name = cls.allowed_classes.get(key).get('name')

                # If the modality name is not found_classes, add it
                if modality_name not in found_classes \
                        and modality_name in required_classes:
                    found_classes.add(modality_name)

        # Get the difference between required classes and found classes
        class_diff = set(required_classes).difference(found_classes)

        # If the dataset is missing required files, pass on it
        if len(class_diff) > 0:
            print("Skipping dataset. Missing required file(s) {}".format(
                class_diff))
            return False

        # Try to get the datasets from the selected files
        try:
            # Convert paths to a common file system representation
            for i, file in enumerate(files):
                files[i] = Path(file).as_posix()
            read_data_dict, file_names_dict = cls.get_datasets(files)
            path = os.path.dirname(
                os.path.commonprefix(list(file_names_dict.values())))
        # Otherwise raise an exception (OnkoDICOM does not support the
        # selected file type)
        except ImageLoading.NotAllowedClassError:
            raise ImageLoading.NotAllowedClassError

        # Populate the initial values in the PatientDictContainer
        patient_dict_container = PatientDictContainer()
        patient_dict_container.clear()
        patient_dict_container.set_initial_values(path, read_data_dict,
                                                  file_names_dict)

        # If an RT Struct is included, set relevant values in the
        # PatientDictContainer
        if 'rtss' in file_names_dict:
            dataset_rtss = dcmread(file_names_dict['rtss'])
            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)

            # Add RT Struct values to PatientDictContainer
            patient_dict_container.set("rois", 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)

        return True