diff --git a/fsl/data/dicom.py b/fsl/data/dicom.py index 8c8b8a7e73cd5f9e1375409edd04835f21b69a95..f09383dcc8f4e0bb203fb748b9ebf15811ce4021 100644 --- a/fsl/data/dicom.py +++ b/fsl/data/dicom.py @@ -32,6 +32,7 @@ import re import glob import json import logging +import deprecation import nibabel as nib @@ -48,44 +49,63 @@ class DicomImage(fslimage.Image): DICOM metadata. The ``Image`` class is used to manage the data and the voxel-to-world - transformation. Additional DICOM metadata may be accessed via TODO + transformation. Additional DICOM metadata may be accessed via the + :class:`.Image` metadata access methods. """ - def __init__(self, image, meta, *args, **kwargs): + + def __init__(self, image, metadata, dicomDir, *args, **kwargs): """Create a ``DicomImage``. - :arg image: Passed through to :meth:`.Image.__init__`. - :arg meta: Dictionary containing DICOM meta-data. + :arg image: Passed through to :meth:`.Image.__init__`. + :arg metadata: Dictionary containing DICOM meta-data. + :arg dicomDir: Directory that the dicom image was loaded from. """ fslimage.Image.__init__(self, image, *args, **kwargs) - self.__meta = meta + + self.__dicomDir = dicomDir + + if metadata is not None: + for k, v in metadata.items(): + self.addMeta(k, v) + + + @property + def dicomDir(self): + """Returns the directory that the DICOM image data was loaded from. """ + return self.__dicomDir + @deprecation.deprecated(deprecated_in='1.6.0', + removed_in='2.0.0', + details='Use metaKeys instead') def keys(self): - """Returns the keys contained in the DICOM metadata dictionary - (``dict.keys``). - """ - return self.__meta.keys() + """Deprecated - use :meth:`.Image.metaKeys`. """ + return self.metaKeys() + @deprecation.deprecated(deprecated_in='1.6.0', + removed_in='2.0.0', + details='Use metaValues instead') def values(self): - """Returns the values contained in the DICOM metadata dictionary - (``dict.values``). - """ - return self.__meta.values() + """Deprecated - use :meth:`.Image.metaValues`. """ + return self.metaValues() + @deprecation.deprecated(deprecated_in='1.6.0', + removed_in='2.0.0', + details='Use metaItems instead') def items(self): - """Returns the items contained in the DICOM metadata dictionary - (``dict.items``). - """ - return self.__meta.items() + """Deprecated - use :meth:`.Image.metaItems`. """ + return self.metaItems() + @deprecation.deprecated(deprecated_in='1.6.0', + removed_in='2.0.0', + details='Use getMeta instead') def get(self, *args, **kwargs): - """Returns the metadata value with the specified key (``dict.get``). - """ - return self.__meta.get(*args, **kwargs) + """Deprecated - use :meth:`.Image.getMeta`. """ + return self.getMeta(*args, **kwargs) @memoize.memoize @@ -218,4 +238,4 @@ def loadSeries(series): # Force-load images into memory [i.get_data() for i in images] - return [DicomImage(i, series, name=desc) for i in images] + return [DicomImage(i, series, dcmdir, name=desc) for i in images] diff --git a/fsl/data/image.py b/fsl/data/image.py index 0afc47c7473690970554cea7aab95ec385bcfd45..32da2f14b06eca040593381bd1660d73c52746a5 100644 --- a/fsl/data/image.py +++ b/fsl/data/image.py @@ -36,6 +36,7 @@ import os import os.path as op import string import logging +import collections import six import deprecation @@ -158,6 +159,23 @@ class Nifti(notifier.Notifier): :attr:`.constants.NIFTI_XFORM_ANALYZE`. + **Metadata** + + + The ``Image`` class has a handful of methods allowing you to add and access + additional metadata associated with the image. These methods are used by + the :class:`.DicomImage` and :class:`.MGHImage` to store additional + meta-data that cannot be stored in the NIFTI header: + + .. autosummary:: + :nosignatures: + + metaKeys + metaValues + metaItems + getMeta + + **Notification** @@ -193,6 +211,7 @@ class Nifti(notifier.Notifier): worldToVoxMat = transform.invert(voxToWorldMat) self.header = header + self.__meta = collections.OrderedDict() self.__shape = shape self.__intent = header.get('intent_code', constants.NIFTI_INTENT_NONE) @@ -667,6 +686,33 @@ class Nifti(notifier.Notifier): return code + def metaKeys(self): + """Returns the keys contained in the image metadata dictionary + (``dict.keys``). + """ + return self.__meta.keys() + + + def metaValues(self): + """Returns the values contained in the image metadata dictionary + (``dict.values``). + """ + return self.__meta.values() + + + def metaItems(self): + """Returns the items contained in the image metadata dictionary + (``dict.items``). + """ + return self.__meta.items() + + + def getMeta(self, *args, **kwargs): + """Returns the metadata value with the specified key (``dict.get``). + """ + return self.__meta.get(*args, **kwargs) + + class Image(Nifti): """Class which represents a NIFTI image. Internally, the image is loaded/stored using a :mod:`nibabel.nifti1.Nifti1Image` or @@ -831,7 +877,7 @@ class Image(Nifti): # Otherwise we let nibabel # manage the file reference(s) else: - nibImage = nib.load(image, **kwargs) + nibImage = nib.load(image, **kwargs) dataSource = image @@ -1311,7 +1357,7 @@ Made available in this module for convenience. def looksLikeImage(filename, allowedExts=None): - """Returns ``True`` if the given file looks like an image, ``False`` + """Returns ``True`` if the given file looks like a NIFTI image, ``False`` otherwise. .. note:: The ``filename`` cannot just be a file prefix - it must