Пример #1
0
def test_too_many_headers_file(tmpdir):
    # Generate test file...
    test_file_path = Path(tmpdir) / "test.mhd"
    with open(test_file_path, "w", encoding="utf-8") as f:
        for i in range(1000000):
            f.write(f"key{i} = {i}\n")

    with pytest.raises(ValidationError):
        parse_mh_header(test_file_path)
Пример #2
0
def test_line_too_long(tmpdir):
    # Generate test file...
    test_file_path = Path(tmpdir) / "test.mhd"
    with open(test_file_path, "w", encoding="utf-8") as f:
        f.write("key = ")
        for i in range(1000000):
            f.write(f"{i}")

    with pytest.raises(ValidationError):
        parse_mh_header(test_file_path)
    def get_mh_header(self) -> Mapping[str, Union[str, None]]:
        """
        Return header from mhd/mha file as key value pairs

        Returns
        -------
            MetaIO headers as key value pairs.

        Raises
        ------
        FileNotFoundError
            Raised when Image has no related mhd/mha ImageFile or actual file
            cannot be found on storage
        """

        mh_file = None
        try:
            mh_file = self.files.get(image_type=ImageFile.IMAGE_TYPE_MHD,
                                     file__endswith=".mha")
        except ObjectDoesNotExist:
            # Fallback to files that are still stored as mhd/(z)raw
            mh_file = self.files.get(image_type=ImageFile.IMAGE_TYPE_MHD,
                                     file__endswith=".mhd")

        if mh_file is None or not mh_file.file.storage.exists(
                name=mh_file.file.name):
            raise FileNotFoundError(f"No file found for {mh_file.file}")

        return parse_mh_header(mh_file.file)
Пример #4
0
def test_does_not_choke_on_empty_file(tmpdir):
    # Generate test file...
    test_file_path = Path(tmpdir) / "test.mhd"
    with open(test_file_path, "w", encoding="utf-8") as f:
        f.write("\n")

    assert parse_mh_header(test_file_path) == {}
Пример #5
0
    def get_mh_header(self) -> Mapping[str, Union[str, None]]:
        """
        Return header from mhd/mha file as key value pairs

        Returns
        -------
            MetaIO headers as key value pairs.

        Raises
        ------
        FileNotFoundError
            Raised when Image has no related mhd/mha ImageFile or actual file
            cannot be found on storage
        """

        mh_file, _ = self.get_metaimage_files()
        return parse_mh_header(mh_file.file)
def test_image_builder_dicom_4dct(tmpdir):
    files = {Path(d[0]).joinpath(f) for d in os.walk(DICOM_DIR) for f in d[2]}
    result = _build_files(builder=image_builder_dicom,
                          files=files,
                          output_directory=tmpdir)
    assert result.consumed_files == {
        Path(DICOM_DIR).joinpath(f"{x}.dcm")
        for x in range(1, 77)
    }

    assert len(result.new_images) == 1
    image = Image(**asdict(result.new_images.pop()))
    assert image.shape == [19, 4, 2, 3]
    assert len(result.new_image_files) == 1
    mha_file_obj = [
        x for x in result.new_image_files if x.file.suffix == ".mha"
    ][0]

    headers = parse_mh_header(mha_file_obj.file)

    direction = headers["TransformMatrix"].split()
    origin = headers["Offset"].split()
    spacing = headers["ElementSpacing"].split()
    exposures = headers["Exposures"].split()
    content_times = headers["ContentTimes"].split()

    assert len(exposures) == 19
    assert exposures == [str(x) for x in range(100, 2000, 100)]
    assert len(content_times) == 19
    assert content_times == [str(x) for x in range(214501, 214520)]

    dcm_ref = pydicom.dcmread(str(DICOM_DIR / "1.dcm"))
    assert np.array_equal(
        np.array(list(map(float, direction))).reshape((4, 4)), np.eye(4))
    assert np.allclose(
        list(map(float, spacing))[:2],
        list(map(
            float,
            list(dcm_ref.PixelSpacing),
        )),
    )
    assert np.allclose(
        list(map(float, origin)),
        list(map(float, dcm_ref.ImagePositionPatient)) + [0.0],
    )
Пример #7
0
def test_parse_header_valid_mhd():
    headers = parse_mh_header(RESOURCE_PATH / "image10x10x10.mhd")
    assert headers == {
        "ObjectType": "Image",
        "NDims": "3",
        "BinaryData": "True",
        "BinaryDataByteOrderMSB": "False",
        "CompressedData": "True",
        "CompressedDataSize": "7551",
        "TransformMatrix": "1 0 0 0 1 0 0 0 1",
        "Offset": "0 0 0",
        "CenterOfRotation": "0 0 0",
        "AnatomicalOrientation": "RAI",
        "ElementSpacing": "1 1 1",
        "DimSize": "10 10 10",
        "ElementType": "MET_DOUBLE",
        "ElementDataFile": "image10x10x10.zraw",
    }
Пример #8
0
def test_parse_header_valid_4d_mhd():
    headers = parse_mh_header(RESOURCE_PATH / "image10x11x12x13.mhd")
    assert headers == {
        "ObjectType": "Image",
        "NDims": "4",
        "BinaryData": "True",
        "BinaryDataByteOrderMSB": "False",
        "CompressedData": "True",
        "CompressedDataSize": "39",
        "TransformMatrix": "1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1",
        "Offset": "-131 -99 -917 0",
        "CenterOfRotation": "0 0 0 0",
        "AnatomicalOrientation": "RAI",
        "ElementSpacing": "0.429 0.429 0.5 1",
        "DimSize": "10 11 12 13",
        "ElementType": "MET_UCHAR",
        "ElementDataFile": "image10x11x12x13.zraw",
    }
Пример #9
0
def test_staged_mhd_upload_with_additional_headers(
    settings, tmp_path, images: List[str]
):
    # Override the celery settings
    settings.task_eager_propagates = (True,)
    settings.task_always_eager = (True,)

    session, uploaded_images = create_raw_upload_image_session(images=images)

    session.refresh_from_db()
    assert session.status == session.SUCCESS
    assert session.error_message is None

    images = Image.objects.filter(origin=session).all()
    assert len(images) == 1

    raw_image_file: RawImageFile = list(uploaded_images.values())[0]
    raw_image_file.refresh_from_db()
    assert raw_image_file.staged_file_id is None

    image: Image = images[0]
    tmp_header_filename = tmp_path / "tmp_header.mhd"
    with image.files.get(file__endswith=".mha").file.open(
        "rb"
    ) as in_file, open(tmp_header_filename, "wb") as out_file:
        out_file.write(in_file.read())

    headers = parse_mh_header(tmp_header_filename)
    for key in headers.keys():
        assert (key in ADDITIONAL_HEADERS) or (key in EXPECTED_HEADERS)

    sitk_image: SimpleITK.Image = image.get_sitk_image()
    for key in ADDITIONAL_HEADERS:
        assert key in sitk_image.GetMetaDataKeys()
        if key in HEADERS_MATCHING_NUM_TIMEPOINTS:
            if sitk_image.GetDimension() >= 4:
                assert (
                    len(sitk_image.GetMetaData(key).split(" "))
                    == sitk_image.GetSize()[3]
                )
            else:
                assert len(sitk_image.GetMetaData(key).split(" ")) == 1
    assert "Bogus" not in sitk_image.GetMetaDataKeys()
def test_dicom_rescaling(folder, element_type, tmpdir):
    """
    2.dcm in dicom_intercept and dicom_slope has been modified to add a
    small intercept (0.01) or slope (1.001) respectively.
    """
    files = [
        Path(d[0]).joinpath(f) for d in os.walk(RESOURCE_PATH / folder)
        for f in d[2]
    ]
    result = _build_files(builder=image_builder_dicom,
                          files=files,
                          output_directory=tmpdir)

    assert len(result.new_image_files) == 1
    mha_file_obj = [
        x for x in result.new_image_files if x.file.suffix == ".mha"
    ][0]

    headers = parse_mh_header(mha_file_obj.file)
    assert headers["ElementType"] == element_type
def test_dicom_window_level(tmpdir):
    files = {
        Path(d[0]).joinpath(f)
        for d in os.walk(RESOURCE_PATH / "dicom") for f in d[2]
    }
    result = _build_files(builder=image_builder_dicom,
                          files=files,
                          output_directory=tmpdir)

    assert len(result.new_image_files) == 1
    mha_file_obj = [
        x for x in result.new_image_files if x.file.suffix == ".mha"
    ][0]

    headers = parse_mh_header(mha_file_obj.file)
    assert headers["WindowCenter"] == "30"
    assert headers["WindowWidth"] == "200"

    assert len(result.new_images) == 1
    image_obj = result.new_images.pop()
    assert image_obj.window_center == 30.0
    assert image_obj.window_width == 200.0
Пример #12
0
def test_fail_on_invalid_utf8():
    with pytest.raises(ValidationError):
        parse_mh_header(RESOURCE_PATH / "invalid_utf8.mhd")