From 43038ecbcfe3c6b7e56db12dbf5e0e7a0fe1629b Mon Sep 17 00:00:00 2001 From: Tom Close Date: Sat, 28 Sep 2024 10:02:20 +1000 Subject: [PATCH] added MedicalImagingData base class --- .../extras/medimage/tests/test_deidentify.py | 4 +++ fileformats/medimage/__init__.py | 3 +- fileformats/medimage/base.py | 32 +++++++++++-------- fileformats/medimage/raw/pet/base.py | 3 +- 4 files changed, 27 insertions(+), 15 deletions(-) diff --git a/extras/fileformats/extras/medimage/tests/test_deidentify.py b/extras/fileformats/extras/medimage/tests/test_deidentify.py index 16bc0b3..241e3bf 100644 --- a/extras/fileformats/extras/medimage/tests/test_deidentify.py +++ b/extras/fileformats/extras/medimage/tests/test_deidentify.py @@ -21,8 +21,12 @@ def dicom(request): def test_deidentify_dicom(dicom): assert str(dicom.metadata["PatientName"]) == "Doe^John" + assert dicom.metadata["InstitutionAddress"] + assert not dicom.metadata["PatientBirthDate"].endswith("0101") deidentified = dicom.deidentify() assert str(deidentified.metadata["PatientName"]) == "Anonymous^Anonymous" + assert deidentified.metadata["InstitutionAddress"] == "" + assert deidentified.metadata["PatientBirthDate"] == "19800101" def test_nifti_deidentify(): diff --git a/fileformats/medimage/__init__.py b/fileformats/medimage/__init__.py index d4eeab1..5df25f4 100644 --- a/fileformats/medimage/__init__.py +++ b/fileformats/medimage/__init__.py @@ -1,5 +1,5 @@ from ._version import __version__ -from .base import MedicalImage +from .base import MedicalImagingData, MedicalImage from .misc import ( @@ -128,6 +128,7 @@ __all__ = [ "__version__", + "MedicalImagingData", "MedicalImage", "DicomImage", "Analyze", diff --git a/fileformats/medimage/base.py b/fileformats/medimage/base.py index 0e8d89f..43a43b0 100644 --- a/fileformats/medimage/base.py +++ b/fileformats/medimage/base.py @@ -33,7 +33,25 @@ ) # In Py<3.9 this is problematic "numpy.typing.NDArray[typing.Union[numpy.floating[typing.Any], numpy.integer[typing.Any]]]" -class MedicalImage(WithClassifiers, FileSet): +class MedicalImagingData(FileSet): + """Base class for all medical imaging data including pre-image raw data and + associated data""" + + contains_phi: bool = True + + @extra + def deidentify( + self, + out_dir: ty.Optional[Path] = None, + new_stem: ty.Optional[str] = None, + copy_mode: FileSet.CopyMode = FileSet.CopyMode.copy, + ) -> Self: + """Returns a new copy of the image with any subject-identifying information + stripped from the from the image header""" + raise NotImplementedError + + +class MedicalImage(WithClassifiers, MedicalImagingData): INCLUDE_HDR_KEYS: ty.Optional[ty.Tuple[str, ...]] = None IGNORE_HDR_KEYS: ty.Optional[ty.Tuple[str, ...]] = None @@ -42,7 +60,6 @@ class MedicalImage(WithClassifiers, FileSet): image_contents = () allowed_classifiers = (ContentsClassifier,) exclusive_classifiers = (ImagingModality, AnatomicalEntity, Derivative) - contains_phi: bool = True @extra def read_array(self) -> DataArrayType: @@ -63,14 +80,3 @@ def vox_sizes(self) -> ty.Tuple[float, float, float]: def dims(self) -> ty.Tuple[int, int, int]: """The dimensions of the image""" raise NotImplementedError - - @extra - def deidentify( - self, - out_dir: ty.Optional[Path] = None, - new_stem: ty.Optional[str] = None, - copy_mode: FileSet.CopyMode = FileSet.CopyMode.copy, - ) -> Self: - """Returns a new copy of the image with any subject-identifying information - stripped from the from the image header""" - raise NotImplementedError diff --git a/fileformats/medimage/raw/pet/base.py b/fileformats/medimage/raw/pet/base.py index 407fe8c..1ad0ef8 100644 --- a/fileformats/medimage/raw/pet/base.py +++ b/fileformats/medimage/raw/pet/base.py @@ -2,6 +2,7 @@ import typing as ty from pathlib import Path from fileformats.core import FileSet, extra +from fileformats.medimage import MedicalImagingData from fileformats.generic import BinaryFile if sys.version_info >= (3, 12): @@ -10,7 +11,7 @@ from typing_extensions import Self -class PetRawData(BinaryFile): +class PetRawData(BinaryFile, MedicalImagingData): """Base class for raw PET data files""" @extra