From c24eaeca5ac3115f8702274346f4f590bbd83f94 Mon Sep 17 00:00:00 2001
From: Paul McCarthy <pauldmccarthy@gmail.com>
Date: Fri, 19 Jan 2018 15:29:02 +0000
Subject: [PATCH] Nifti.meta* methods are now in a base-class. Also used by
 TriangleMesh.

---
 fsl/data/image.py | 52 +++-----------------------------------
 fsl/data/mesh.py  |  3 ++-
 fsl/utils/meta.py | 64 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 70 insertions(+), 49 deletions(-)
 create mode 100644 fsl/utils/meta.py

diff --git a/fsl/data/image.py b/fsl/data/image.py
index 9a9869d34..4c22ad402 100644
--- a/fsl/data/image.py
+++ b/fsl/data/image.py
@@ -46,6 +46,7 @@ import scipy.ndimage     as ndimage
 import nibabel           as nib
 import nibabel.fileslice as fileslice
 
+import fsl.utils.meta        as meta
 import fsl.utils.transform   as transform
 import fsl.utils.notifier    as notifier
 import fsl.utils.memoize     as memoize
@@ -57,7 +58,7 @@ import fsl.data.imagewrapper as imagewrapper
 log = logging.getLogger(__name__)
 
 
-class Nifti(notifier.Notifier):
+class Nifti(notifier.Notifier, meta.Meta):
     """The ``Nifti`` class is intended to be used as a base class for
     things which either are, or are associated with, a NIFTI image.
     The ``Nifti`` class is intended to represent information stored in
@@ -162,19 +163,8 @@ class Nifti(notifier.Notifier):
     **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
-       setMeta
+    The ``Image`` class inherits from the :class:`.Meta` class - its methods
+    can be used to store and query any meta-data associated with the image.
 
 
     **Notification**
@@ -212,7 +202,6 @@ 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)
@@ -687,39 +676,6 @@ 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)
-
-
-    def setMeta(self, *args, **kwargs):
-        """Add some metadata with the specified key (``dict.__setitem__``).
-        """
-        self.__meta.__setitem__(*args, **kwargs)
-
-
 class Image(Nifti):
     """Class which represents a NIFTI image. Internally, the image is
     loaded/stored using a :mod:`nibabel.nifti1.Nifti1Image` or
diff --git a/fsl/data/mesh.py b/fsl/data/mesh.py
index 1ad40139e..a979c01cc 100644
--- a/fsl/data/mesh.py
+++ b/fsl/data/mesh.py
@@ -27,6 +27,7 @@ import numpy   as np
 
 import six
 
+import fsl.utils.meta      as meta
 import fsl.utils.memoize   as memoize
 import fsl.utils.transform as transform
 
@@ -36,7 +37,7 @@ from . import image as fslimage
 log = logging.getLogger(__name__)
 
 
-class TriangleMesh(object):
+class TriangleMesh(meta.Meta):
     """The ``TriangleMesh`` class represents a 3D model. A mesh is defined by a
     collection of ``N`` vertices, and ``M`` triangles.  The triangles are
     defined by ``(M, 3)`` indices into the list of vertices.
diff --git a/fsl/utils/meta.py b/fsl/utils/meta.py
new file mode 100644
index 000000000..f380fdbf1
--- /dev/null
+++ b/fsl/utils/meta.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+#
+# meta.py - The Meta class/mixin.
+#
+# Author: Paul McCarthy <pauldmccarthy@gmail.com>
+#
+"""This module provides the :class:`Meta` class. """
+
+
+import collections
+
+
+class Meta(object):
+    """The ``Meta`` class is intended to be used as a mixin for other classes. It
+    is simply a wrapper for a dictionary of key-value pairs.
+
+    It has a handful of methods allowing you to add and access additional
+    metadata associated with an object.
+
+    .. autosummary::
+       :nosignatures:
+
+       metaKeys
+       metaValues
+       metaItems
+       getMeta
+       setMeta
+    """
+
+    def __init__(self):
+        self.__meta = collections.OrderedDict()
+
+
+    def metaKeys(self):
+        """Returns the keys contained in the metadata dictionary
+        (``dict.keys``).
+        """
+        return self.__meta.keys()
+
+
+    def metaValues(self):
+        """Returns the values contained in the metadata dictionary
+        (``dict.values``).
+        """
+        return self.__meta.values()
+
+
+    def metaItems(self):
+        """Returns the items contained in the 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)
+
+
+    def setMeta(self, *args, **kwargs):
+        """Add some metadata with the specified key (``dict.__setitem__``).
+        """
+        self.__meta.__setitem__(*args, **kwargs)
-- 
GitLab