Skip to content

Commit

Permalink
Fix extra metadata defaults (#54)
Browse files Browse the repository at this point in the history
* Add and set extra metadata default values correctly

* Add new and adapt existing tests

* Bump version
  • Loading branch information
HarmvZ authored Oct 4, 2021
1 parent b0a8ece commit 9c2875a
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 28 deletions.
4 changes: 4 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# History

## 0.5.1 (2021-10-04)

* Fix default values for extra metadata fields

## 0.5.0 (2021-10-01)

* Added extra metadata fields to PanImg object
Expand Down
2 changes: 1 addition & 1 deletion panimg/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "0.5.0"
__version__ = "0.5.1"

import logging

Expand Down
48 changes: 26 additions & 22 deletions panimg/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class PatientSex(str, Enum):
MALE = "M"
FEMALE = "F"
OTHER = "O"
EMPTY = ""


DICOM_VR_TO_VALIDATION_REGEXP = {
Expand All @@ -66,6 +67,7 @@ class ExtraMetaData(NamedTuple):
keyword: str # DICOM tag keyword (eg. 'PatientID')
vr: str # DICOM Value Representation (eg. 'LO')
field_name: str # Name of field on PanImg model (eg. 'patient_id')
default_value: Any # Default value for field

@property
def match_pattern(self):
Expand Down Expand Up @@ -99,16 +101,16 @@ def validate_metadata_value(*, key, value):


EXTRA_METADATA = (
ExtraMetaData("PatientID", "LO", "patient_id"),
ExtraMetaData("PatientName", "PN", "patient_name"),
ExtraMetaData("PatientBirthDate", "DA", "patient_birth_date"),
ExtraMetaData("PatientAge", "AS", "patient_age"),
ExtraMetaData("PatientSex", "CS", "patient_sex"),
ExtraMetaData("StudyDate", "DA", "study_date"),
ExtraMetaData("StudyInstanceUID", "UI", "study_instance_uid"),
ExtraMetaData("SeriesInstanceUID", "UI", "series_instance_uid"),
ExtraMetaData("StudyDescription", "LO", "study_description"),
ExtraMetaData("SeriesDescription", "LO", "series_description"),
ExtraMetaData("PatientID", "LO", "patient_id", ""),
ExtraMetaData("PatientName", "PN", "patient_name", ""),
ExtraMetaData("PatientBirthDate", "DA", "patient_birth_date", None),
ExtraMetaData("PatientAge", "AS", "patient_age", ""),
ExtraMetaData("PatientSex", "CS", "patient_sex", ""),
ExtraMetaData("StudyDate", "DA", "study_date", None),
ExtraMetaData("StudyInstanceUID", "UI", "study_instance_uid", ""),
ExtraMetaData("SeriesInstanceUID", "UI", "series_instance_uid", ""),
ExtraMetaData("StudyDescription", "LO", "study_description", ""),
ExtraMetaData("SeriesDescription", "LO", "series_description", ""),
)


Expand All @@ -128,16 +130,16 @@ class PanImg:
window_width: Optional[float]
color_space: ColorSpace
eye_choice: EyeChoice
patient_id: Optional[str]
patient_name: Optional[str]
patient_birth_date: Optional[datetime.date]
patient_age: Optional[str]
patient_sex: Optional[PatientSex]
study_date: Optional[datetime.date]
study_instance_uid: Optional[str]
series_instance_uid: Optional[str]
study_description: Optional[str]
series_description: Optional[str]
patient_id: str = ""
patient_name: str = ""
patient_birth_date: Optional[datetime.date] = None
patient_age: str = ""
patient_sex: PatientSex = PatientSex.EMPTY
study_date: Optional[datetime.date] = None
study_instance_uid: str = ""
series_instance_uid: str = ""
study_description: str = ""
series_description: str = ""


@dataclass(frozen=True)
Expand Down Expand Up @@ -266,7 +268,9 @@ def voxel_depth_mm(self) -> Optional[float]:
return None

def generate_extra_metadata(self,) -> Dict[str, Any]:
extra_metadata = {md.field_name: None for md in EXTRA_METADATA}
extra_metadata = {
md.field_name: md.default_value for md in EXTRA_METADATA
}
for md in EXTRA_METADATA:
try:
value = str(self.image.GetMetaData(md.keyword))
Expand Down Expand Up @@ -365,7 +369,7 @@ def save(self, output_directory: Path) -> Tuple[PanImg, Set[PanImgFile]]:
window_center=None,
window_width=None,
eye_choice=self.eye_choice,
**{md.field_name: None for md in EXTRA_METADATA},
**{md.field_name: md.default_value for md in EXTRA_METADATA},
)

shutil.copy(src=self.file, dst=output_file)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ commands =

[tool.poetry]
name = "panimg"
version = "0.5.0"
version = "0.5.1"
description = "Conversion of medical images to MHA and TIFF."
license = "Apache-2.0"
authors = ["James Meakin <[email protected]>"]
Expand Down
22 changes: 20 additions & 2 deletions tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from panimg.exceptions import ValidationError
from panimg.image_builders.metaio_utils import load_sitk_image
from panimg.models import ExtraMetaData, SimpleITKImage
from panimg.models import EXTRA_METADATA, ExtraMetaData, SimpleITKImage
from tests import RESOURCE_PATH


Expand Down Expand Up @@ -51,7 +51,7 @@
),
)
def test_dicom_vr_validation(vr, valid, invalid):
md = ExtraMetaData("Test", vr, "test")
md = ExtraMetaData("Test", vr, "test", "default")
for t in valid:
md.validate_value(t)

Expand Down Expand Up @@ -90,3 +90,21 @@ def test_built_image_invalid_headers(tmpdir, caplog, key, value):
warning = caplog.records[0]
assert warning.levelno == logging.WARNING
assert "ValidationError" in warning.msg


def test_built_image_extra_metadata_defaults(tmpdir, caplog):
src = RESOURCE_PATH / "image3x4.mhd"
sitk_image = load_sitk_image(src)
result = SimpleITKImage(
image=sitk_image,
name=src.name,
consumed_files={src},
spacing_valid=True,
)
new_image, new_files = result.save(output_directory=tmpdir)
assert len(caplog.records) == 0
expected_default_values = {
md.field_name: md.default_value for md in EXTRA_METADATA
}
for key, val in expected_default_values.items():
assert getattr(new_image, key) == val
2 changes: 1 addition & 1 deletion tests/test_panimg.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@


def test_version():
assert __version__ == "0.5.0"
assert __version__ == "0.5.1"
2 changes: 1 addition & 1 deletion tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def assert_img_properties(
if md.keyword in md_keys:
assert value == md.cast_func(img.GetMetaData(md.keyword))
else:
assert value is None
assert value is md.default_value

img_ref = load_sitk_image(image)
internal_image = SimpleITKImage(
Expand Down

0 comments on commit 9c2875a

Please sign in to comment.