Source code for dosma.data_io.format_io
"""I/O formatting templates.
This module consists of the templates for input/output (I/O) helper classes.
Attributes:
SUPPORTED_VISUALIZATION_FORMATS (tuple[str]): Image formats that are
supported for visualization.
"""
import enum
import os
from abc import ABC, abstractmethod
__all__ = ["ImageDataFormat", "DataReader", "DataWriter", "SUPPORTED_VISUALIZATION_FORMATS"]
SUPPORTED_VISUALIZATION_FORMATS = (
"png",
"eps",
"pdf",
"jpeg",
"pgf",
"ps",
"raw",
"rgba",
"svg",
"svgz",
"tiff",
)
[docs]class ImageDataFormat(enum.Enum):
"""Enum describing supported data formats for medical volume I/O.
"""
nifti = 1, ("nii", "nii.gz")
dicom = 2, ("dcm",)
def __new__(cls, key_code, extensions):
"""
Args:
key_code (int): Enum value.
extensions (tuple[str]): Extensions supported by format.
"""
obj = object.__new__(cls)
obj._value_ = key_code
obj.extensions = extensions
return obj
[docs] def is_filetype(self, file_path: str) -> bool:
"""Verify if file path matches the file type specified by ImageDataFormat.
This method checks to make sure the extensions are appropriate.
Args:
file_path (str): File path.
Returns:
bool: True if file_path has valid extension, False otherwise.
"""
bool_list = [file_path.endswith(".%s" % ext) for ext in self.extensions]
return bool(sum(bool_list))
[docs] @classmethod
def get_image_data_format(cls, file_or_dir_path: str):
"""Get the `ImageDataFormat` that corresponds to the file path.
Matches extension to file path. If input is a directory path, then
it is classified as `ImageDataFormat.dicom`.
Args:
file_or_dir_path (str): Path to a file or a directory.
Returns:
ImageDataFormat: Format corresponding to file or directory path.
Raises:
ValueError: If no compatible ImageDataFormat found.
"""
for im_data_format in cls:
if im_data_format.is_filetype(file_or_dir_path):
return im_data_format
# if no extension found, assume the name corresponds to a directory
# and assume that format is dicom
filename_base, ext = os.path.splitext(file_or_dir_path)
if filename_base == file_or_dir_path:
return ImageDataFormat.dicom
raise ValueError("Unknown data format for %s" % file_or_dir_path)
[docs]class DataReader(ABC):
"""Abstract class for reading medical data.
Format-specific readers should inherit from this class.
Attributes:
data_format_code (ImageDataFormat): Should be defined by subclasses.
"""
data_format_code = None
[docs] @abstractmethod
def load(self, file_path: str):
"""Load volume.
Args:
file_path (str): File path to load volume from.
Returns:
MedicalVolume: The loaded volume.
"""
pass
[docs]class DataWriter(ABC):
"""Abstract class for writing medical data.
Format-specific writers should inherit from this class.
Attributes:
data_format_code (ImageDataFormat): Should be defined by subclasses.
"""
data_format_code = None
[docs] @abstractmethod
def save(self, volume, file_path: str):
"""Save volume.
Args:
volume (MedicalVolume): Volume to save.
file_path (str): File path to save volume to.
"""
pass