Ejemplo n.º 1
0
def convert_nifti_to_zipped_dicom_rt(nifti_file: Path, reference_series: Path,
                                     scratch_folder: Path,
                                     config: SegmentationModelBase) -> Path:
    """
    Given a Nifti file and a reference DICOM series, create zip file containing a DICOM-RT file.

    Calls rtconvert with the given Nifti file, reference DICOM series and configuration from
    config to create a DICOM-RT file in the scratch folder. This is then zipped and a path to
    the zip returned.

    :param nifti_file: Path to Nifti file.
    :param reference_series: Path to folder containing reference DICOM series.
    :param scratch_folder: Scratch folder to extract files into.
    :param config: Model config.
    :return: Path to DICOM-RT file.
    """
    dicom_rt_file = scratch_folder / nifti_file.with_suffix(".dcm").name
    (stdout,
     stderr) = rtconvert(in_file=nifti_file,
                         reference_series=reference_series,
                         out_file=dicom_rt_file,
                         struct_names=config.ground_truth_ids_display_names,
                         struct_colors=[
                             convert_rgb_colour_to_hex(rgb)
                             for rgb in config.colours
                         ],
                         fill_holes=config.fill_holes)
    # Log stdout, stderr from DICOM-RT conversion.
    logging.debug("stdout: %s", stdout)
    logging.debug("stderr: %s", stderr)
    dicom_rt_zip_file = dicom_rt_file.with_suffix(dicom_rt_file.suffix +
                                                  '.zip')
    with zipfile.ZipFile(dicom_rt_zip_file, 'w') as dicom_rt_zip:
        dicom_rt_zip.write(dicom_rt_file, dicom_rt_file.name)
    return dicom_rt_zip_file
def test_rtconvert() -> None:
    """
    Test calling RTConvert for the test data.
    """
    (stdout, stderr) = rtconvert(in_file=TestNiftiSegmentationLocation,
                                 reference_series=TestDicomVolumeLocation,
                                 out_file=TestOutputFile,
                                 struct_names=StructureNames,
                                 struct_colors=StructureColors,
                                 fill_holes=FillHoles,
                                 roi_interpreted_types=ROIInterpretedTypes,
                                 manufacturer=Manufacturer,
                                 interpreter=Interpreter,
                                 modelId=ModelId)

    logger.debug("stdout: %s", stdout)
    logger.debug("stderr: %s", stderr)

    assert stderr == ''
    assert "Successfully written" in stdout

    assert TestOutputFile.is_file()

    with open(TestOutputFile, 'rb') as infile:
        ds = dcmread(infile)

        assert ds is not None

        # Check the modality
        assert ds.Modality == 'RTSTRUCT'

        assert ds.Manufacturer == Manufacturer
        assert ds.SoftwareVersions == ModelId

        assert len(ds.StructureSetROISequence) == len(StructureNames)

        for i, item in enumerate(StructureNames):
            assert ds.StructureSetROISequence[i].ROINumber == i + 1
            assert ds.StructureSetROISequence[i].ROIName == item
            assert Interpreter in ds.RTROIObservationsSequence[
                i].ROIInterpreter
            assert ds.RTROIObservationsSequence[i].RTROIInterpretedType == (
                '' if ROIInterpretedTypes[i] == 'None' else
                ROIInterpretedTypes[i])

        assert len(ds.ROIContourSequence) == len(StructureNames)

        for i, item in enumerate(StructureNames):
            assert ds.ROIContourSequence[i].ReferencedROINumber == i + 1
            assert ds.ROIContourSequence[i].ROIDisplayColor == _parse_rgb(
                StructureColors[i])
Ejemplo n.º 3
0
def convert_nifti_to_zipped_dicom_rt(nifti_file: Path, reference_series: Path,
                                     scratch_folder: Path,
                                     config: SegmentationModelBase,
                                     dicom_rt_zip_file_name: str,
                                     model_id: str) -> Path:
    """
    Given a Nifti file and a reference DICOM series, create zip file containing a DICOM-RT file.

    Calls rtconvert with the given Nifti file, reference DICOM series and configuration from
    config to create a DICOM-RT file in the scratch folder. This is then zipped and a path to
    the zip returned.

    :param nifti_file: Path to Nifti file.
    :param reference_series: Path to folder containing reference DICOM series.
    :param scratch_folder: Scratch folder to extract files into.
    :param config: Model config.
    :param dicom_rt_zip_file_name: Target DICOM-RT zip file name, ending in .dcm.zip.
    :param model_id: The AzureML model ID <model_name>:<ID>
    :return: Path to DICOM-RT file.
    """
    dicom_rt_file_path = scratch_folder / Path(
        dicom_rt_zip_file_name).with_suffix("")
    (stdout,
     stderr) = rtconvert(in_file=nifti_file,
                         reference_series=reference_series,
                         out_file=dicom_rt_file_path,
                         struct_names=config.ground_truth_ids_display_names,
                         struct_colors=[
                             convert_rgb_colour_to_hex(rgb)
                             for rgb in config.colours
                         ],
                         fill_holes=config.fill_holes,
                         roi_interpreted_types=config.roi_interpreted_types,
                         manufacturer=config.manufacturer,
                         interpreter=config.interpreter,
                         modelId=model_id)
    # Log stdout, stderr from DICOM-RT conversion.
    logging.debug("stdout: %s", stdout)
    logging.debug("stderr: %s", stderr)
    dicom_rt_zip_file_path = scratch_folder / dicom_rt_zip_file_name
    with zipfile.ZipFile(dicom_rt_zip_file_path, 'w') as dicom_rt_zip:
        dicom_rt_zip.write(dicom_rt_file_path, dicom_rt_file_path.name)
    return dicom_rt_zip_file_path