diff --git a/fsl/data/strings.py b/fsl/data/strings.py
index bc4a432834e1e270a9ad5bffdd5b4ba053e7f2b1..4a8e771e090ac3beca48b655c6432c13c01bb539 100644
--- a/fsl/data/strings.py
+++ b/fsl/data/strings.py
@@ -527,9 +527,9 @@ properties = TypeDict({
     'Display.brightness'        : 'Brightness',
     'Display.contrast'          : 'Contrast',
 
-    'ImageOpts.resolution' : 'Resolution',
-    'ImageOpts.transform'  : 'Image transform',
-    'ImageOpts.volume'     : 'Volume',
+    'Nifti1Opts.resolution' : 'Resolution',
+    'Nifti1Opts.transform'  : 'Image transform',
+    'Nifti1Opts.volume'     : 'Volume',
     
     'VolumeOpts.displayRange'    : 'Display range',
     'VolumeOpts.clippingRange'   : 'Clipping range',
@@ -616,12 +616,12 @@ choices = TypeDict({
 
     'ModelOpts.refImage.none'     : 'No reference image',
 
-    'ImageOpts.transform' : {'affine' : 'Use qform/sform transformation '
-                                        'matrix',
-                             'pixdim' : 'Use pixdims only',
-                             'id'     : 'Do not use qform/sform or pixdims',
-                             'custom' : 'Apply a custom transformation '
-                                        'matrix'},
+    'Nifti1Opts.transform' : {'affine' : 'Use qform/sform transformation '
+                                         'matrix',
+                              'pixdim' : 'Use pixdims only',
+                              'id'     : 'Do not use qform/sform or pixdims',
+                              'custom' : 'Apply a custom transformation '
+                                         'matrix'},
 
     'VolumeOpts.interpolation' : {'none'   : 'No interpolation', 
                                   'linear' : 'Linear interpolation', 
diff --git a/fsl/fsleyes/controls/locationpanel.py b/fsl/fsleyes/controls/locationpanel.py
index 568d653fb3393b65786a05b3dfa6794aaf58cd28..ead2b822edd92d8636f1b0bb4940cacc2b2bee3a 100644
--- a/fsl/fsleyes/controls/locationpanel.py
+++ b/fsl/fsleyes/controls/locationpanel.py
@@ -113,7 +113,7 @@ class LocationPanel(fslpanel.FSLEyesPanel):
         # this attribute will refer to the
         # corresponding DisplayOpts instance, which
         # has a volume property that controls the
-        # volume - see e.g. the ImageOpts class. This
+        # volume - see e.g. the Nifti1Opts class. This
         # attribute is set in _selectedOverlayChanged.
         self.__volumeTarget = None
 
@@ -425,7 +425,7 @@ class LocationPanel(fslpanel.FSLEyesPanel):
         # Enable/disable the volume widget if the
         # overlay is a 4D image, and bind/unbind
         # the widget to the volume property of
-        # the associated ImageOpts instance
+        # the associated Nifti1Opts instance
         if haveRef and refImage.is4DImage():
             opts = self._displayCtx.getOpts(refImage)
             self.__volumeTarget = opts
diff --git a/fsl/fsleyes/controls/melodicclassificationgrid.py b/fsl/fsleyes/controls/melodicclassificationgrid.py
index a242bd69eb0c61c93e5df19bc1fa021da36deb1f..aa19e52336d61736a398631e79145289d223168f 100644
--- a/fsl/fsleyes/controls/melodicclassificationgrid.py
+++ b/fsl/fsleyes/controls/melodicclassificationgrid.py
@@ -335,7 +335,7 @@ class ComponentGrid(fslpanel.FSLEyesPanel):
 
 
     def __volumeChanged(self, *a):
-        """Called when the :attr:`.ImageOpts.volume` property changes. Selects
+        """Called when the :attr:`.Nifti1Opts.volume` property changes. Selects
         the corresponding row in the :class:`.WidgetGrid`.
         """
 
@@ -613,7 +613,7 @@ class LabelGrid(fslpanel.FSLEyesPanel):
 
     def __onTagSelect(self, ev):
         """Called when a tag from a :class:`.TextTagPanel` is selected.
-        Changes the current :attr:`.ImageOpts.volume` to the component
+        Changes the current :attr:`.Nifti1Opts.volume` to the component
         corresponding to the selected tag.
         """
 
diff --git a/fsl/fsleyes/displaycontext/__init__.py b/fsl/fsleyes/displaycontext/__init__.py
index 0ed0227690e75d27004ce9bf38b8f60c31e78f4a..6158b792dd610d006fb49b8435143257710a9840 100644
--- a/fsl/fsleyes/displaycontext/__init__.py
+++ b/fsl/fsleyes/displaycontext/__init__.py
@@ -72,7 +72,7 @@ new one accordingly.  The following ``DisplayOpts`` sub-classes exist:
 .. autosummary::
    :nosignatures:
 
-   ~fsl.fsleyes.displaycontext.volumeopts.ImageOpts
+   ~fsl.fsleyes.displaycontext.volumeopts.Nifti1Opts
    ~fsl.fsleyes.displaycontext.volumeopts.VolumeOpts
    ~fsl.fsleyes.displaycontext.maskopts.MaskOpts
    ~fsl.fsleyes.displaycontext.vectoropts.VectorOpts
@@ -80,6 +80,7 @@ new one accordingly.  The following ``DisplayOpts`` sub-classes exist:
    ~fsl.fsleyes.displaycontext.vectoropts.LineVectorOpts
    ~fsl.fsleyes.displaycontext.modelopts.ModelOpts
    ~fsl.fsleyes.displaycontext.labelopts.LabelOpts
+   ~fsl.fsleyes.displaycontext.tensoropts.TensorOpts
 
 
 --------------
@@ -142,7 +143,7 @@ from group          import OverlayGroup
 from sceneopts      import SceneOpts
 from orthoopts      import OrthoOpts
 from lightboxopts   import LightBoxOpts
-from volumeopts     import ImageOpts
+from volumeopts     import Nifti1Opts
 from volumeopts     import VolumeOpts
 from maskopts       import MaskOpts
 from vectoropts     import VectorOpts
@@ -150,6 +151,7 @@ from vectoropts     import RGBVectorOpts
 from vectoropts     import LineVectorOpts
 from modelopts      import ModelOpts
 from labelopts      import LabelOpts
+from tensoropts     import TensorOpts
 
 
 from displaycontext import InvalidOverlayError
diff --git a/fsl/fsleyes/displaycontext/display.py b/fsl/fsleyes/displaycontext/display.py
index e7a0f9da1a5171b30d8cdb3af282cb03791c3522..e934a12c307b25d937484d090e41a52080f4b3aa 100644
--- a/fsl/fsleyes/displaycontext/display.py
+++ b/fsl/fsleyes/displaycontext/display.py
@@ -263,7 +263,7 @@ class Display(props.SyncableHasProperties):
 
         Furthermore, in order for the property values of a common
         ``DisplayOpts`` base type to be shared across sub types (e.g. copying
-        the :attr:`.ImageOpts.transform` property between :class:`.VolumeOpts`
+        the :attr:`.Nifti1Opts.transform` property between :class:`.VolumeOpts`
         and :class:`.LabelOpts` instances), we need to store the name of the
         common base type in the dictionary.
 
@@ -337,7 +337,7 @@ class DisplayOpts(props.SyncableHasProperties, actions.ActionProvider):
 
     
     The ``DisplayOpts`` class is not meant to be created directly - it is a
-    base class for type specific implementations (e.g. the :class:`.ImageOpts`
+    base class for type specific implementations (e.g. the :class:`.VolumeOpts`
     class).
 
     
@@ -473,7 +473,7 @@ class DisplayOpts(props.SyncableHasProperties, actions.ActionProvider):
         the display space representation may change - for example, the
         :class:`.Image` overlays can be transformed into the display
         coordinate system in different ways, as defined by the
-        :attr:`.ImageOpts.transform`  property.
+        :attr:`.Nifti1Opts.transform`  property.
         """
         return coords
 
diff --git a/fsl/fsleyes/displaycontext/displaycontext.py b/fsl/fsleyes/displaycontext/displaycontext.py
index a877173e60f913146af868a90d43233628bba5e3..941bd7ba6df49ac791944ba48b3b28362faccba9 100644
--- a/fsl/fsleyes/displaycontext/displaycontext.py
+++ b/fsl/fsleyes/displaycontext/displaycontext.py
@@ -119,36 +119,36 @@ class DisplayContext(props.SyncableHasProperties):
 
     displaySpace = props.Choice(('pixdim', 'world'), default='pixdim')
     """The *space* in which overlays are displayed. This property globally
-    controls the :attr:`.ImageOpts.transform` property of all :class:`.Image`
+    controls the :attr:`.Nifti1Opts.transform` property of all :class:`.Nifti1`
     overlays. It has three settings, described below.
 
     
     1. **Scaled voxel** space (a.k.a. ``pixdim``)
 
-       All :class:`.Image` overlays are displayed with scaled voxels - the
-       :attr:`.ImageOpts.transform` property for every ``Image`` overlay is
+       All :class:`.Nifti1` overlays are displayed with scaled voxels - the
+       :attr:`.Nifti1Opts.transform` property for every ``Nifti1`` overlay is
        set to ``pixdim``.
     
     2. **World** space (a.k.a. ``world``)
 
-       All :class:`.Image` overlays are displayed in the space defined by
-       their affine transformation matrix - the :attr:`.ImageOpts.transform`
-       property for every ``Image`` overlay is set to ``affine``.
+       All :class:`.Nifti1` overlays are displayed in the space defined by
+       their affine transformation matrix - the :attr:`.Nifti1Opts.transform`
+       property for every ``Nifti1`` overlay is set to ``affine``.
 
     3. **Reference image** space
 
-       A single :class:`.Image` overlay is selected as a *reference* image,
-       and is displayed in scaled voxel space (:attr:`.ImageOpts.transform` is
-       set to ``pixdim``). All other ``Image`` overlays are transformed into
-       this reference space - their :attr:`.ImageOpts.transform` property is
-       set to ``custom``, and their :attr:`.ImageOpts.customXform` matrix is
+       A single :class:`.Nifti1` overlay is selected as a *reference* image,
+       and is displayed in scaled voxel space (:attr:`.Nifti1Opts.transform` is
+       set to ``pixdim``). All other ``Nifti1`` overlays are transformed into
+       this reference space - their :attr:`.Nifti1Opts.transform` property is
+       set to ``custom``, and their :attr:`.Nifti1Opts.customXform` matrix is
        set such that it transforms from the image voxel space to the scaled
        voxel space of the reference image.
 
-    .. note:: The :attr:`.ImageOpts.transform` property of any :class:`.Image`
+    .. note:: The :attr:`.Nifti1Opts.transform` property of any :class:`.Nifti1`
               overlay can be set independently of this property. However,
-              whenever this property changes, it will change the ``transform``
-              property for every ``Image``, in the manner described above.
+              whenever *this* property changes, it will change the ``transform``
+              property for every ``Nifti1``, in the manner described above.
     """
 
 
@@ -564,8 +564,8 @@ class DisplayContext(props.SyncableHasProperties):
 
 
     def __setTransform(self, image):
-        """Sets the :attr:`.ImageOpts.transform` property associated with
-        the given :class:`.Image` overlay to a sensible value, given the
+        """Sets the :attr:`.Nifti1Opts.transform` property associated with
+        the given :class:`.Nifti1` overlay to a sensible value, given the
         current value of the :attr:`.displaySpace` property.
 
         Called by the :meth:`__displaySpaceChanged` method, and by
@@ -593,7 +593,7 @@ class DisplayContext(props.SyncableHasProperties):
         
     def __displaySpaceChanged(self, *a):
         """Called when the :attr:`displaySpace` property changes. Updates the
-        :attr:`.ImageOpts.transform` property for all :class:`.Image` overlays
+        :attr:`.Nifti1Opts.transform` property for all :class:`.Nifti1` overlays
         in the :class:`.OverlayList`.
         """
 
diff --git a/fsl/fsleyes/displaycontext/group.py b/fsl/fsleyes/displaycontext/group.py
index a95965433d6af791c0405dd02b450693cc72ce73..4d9885fe297899d97b1eb949cfd7e29393e050f8 100644
--- a/fsl/fsleyes/displaycontext/group.py
+++ b/fsl/fsleyes/displaycontext/group.py
@@ -63,7 +63,7 @@ class OverlayGroup(props.HasProperties):
     
     _groupBindings = td.TypeDict({
         'Display'        : ['enabled'],
-        'ImageOpts'      : ['volume'],
+        'Nifti1Opts'     : ['volume'],
         'VolumeOpts'     : ['interpolation'],
         'LabelOpts'      : ['outline',
                             'outlineWidth'],
@@ -79,6 +79,9 @@ class OverlayGroup(props.HasProperties):
         'LineVectorOpts' : ['lineWidth',
                             'directed'],
         'RGBVectorOpts'  : ['interpolation'],
+        'TensorOpts'     : ['outline',
+                            'lighting',
+                            'tensorResolution'],
     })
     """This dictionary defines the properties which are bound across
     :class:`.Display` instances :class:`.DisplayOpts` sub-class instances, for
@@ -107,14 +110,15 @@ class OverlayGroup(props.HasProperties):
         # classes into the local namespace
         from fsl.fsleyes.displaycontext import \
             Display,        \
-            ImageOpts,      \
+            Nifti1Opts,     \
             VolumeOpts,     \
             MaskOpts,       \
             VectorOpts,     \
             RGBVectorOpts,  \
             LineVectorOpts, \
             ModelOpts,      \
-            LabelOpts
+            LabelOpts,      \
+            TensorOpts
 
         # Add all of the properties listed
         # in the _groupBindings dict as
@@ -130,9 +134,9 @@ class OverlayGroup(props.HasProperties):
                 
                 self.__hasBeenSet[clsName, propName] = False
 
-        # Special case - make sure that the ImageOpts
+        # Special case - make sure that the Nifti1Opts
         # volume property is not constrained
-        self.setConstraint('ImageOpts_volume', 'maxval', sys.maxint)
+        self.setConstraint('Nifti1Opts_volume', 'maxval', sys.maxint)
 
 
     def __copy__(self):
diff --git a/fsl/fsleyes/displaycontext/labelopts.py b/fsl/fsleyes/displaycontext/labelopts.py
index 1665e762d893f5fac04c01b6862de48a571abc27..eca1efa7577cd957af9039cb84666e9c90a6fae4 100644
--- a/fsl/fsleyes/displaycontext/labelopts.py
+++ b/fsl/fsleyes/displaycontext/labelopts.py
@@ -16,7 +16,7 @@ import volumeopts
 import fsl.fsleyes.colourmaps as fslcm
 
 
-class LabelOpts(volumeopts.ImageOpts):
+class LabelOpts(volumeopts.Nifti1Opts):
     """The ``LabelOpts`` class defines settings for displaying
     :class:`.Image` overlays as label images., such as anatomical atlas
     images, tissue segmentation images, and so on.
@@ -47,10 +47,10 @@ class LabelOpts(volumeopts.ImageOpts):
 
     def __init__(self, overlay, *args, **kwargs):
         """Create a ``LabelOpts`` instance for the specified ``overlay``.
-        All arguments are passed through to the :class:`.ImageOpts`
+        All arguments are passed through to the :class:`.Nifti1Opts`
         constructor.
         """
-        volumeopts.ImageOpts.__init__(self, overlay, *args, **kwargs)
+        volumeopts.Nifti1Opts.__init__(self, overlay, *args, **kwargs)
 
         luts  = fslcm.getLookupTables()
         alts  = [[l.name, l.key] for l in luts]
diff --git a/fsl/fsleyes/displaycontext/maskopts.py b/fsl/fsleyes/displaycontext/maskopts.py
index 972f1eb18ca0a7e919c1e096cfdc21fc2c2481ef..24c7cd4370af1fd12515ce4a8764b11a2a33987a 100644
--- a/fsl/fsleyes/displaycontext/maskopts.py
+++ b/fsl/fsleyes/displaycontext/maskopts.py
@@ -17,7 +17,7 @@ import fsl.data.strings as strings
 import                     volumeopts
 
 
-class MaskOpts(volumeopts.ImageOpts):
+class MaskOpts(volumeopts.Nifti1Opts):
     """The ``MaskOpts`` class defines settings for displaying an
     :class:`.Image` overlay as a binary mask.
     """
@@ -42,7 +42,7 @@ class MaskOpts(volumeopts.ImageOpts):
 
     def __init__(self, overlay, *args, **kwargs):
         """Create a ``MaskOpts`` instance for the given overlay. All arguments
-        are passed through to the :class:`.ImageOpts` constructor.
+        are passed through to the :class:`.Nifti1Opts` constructor.
         """
 
         if np.prod(overlay.shape) > 2 ** 30:
@@ -80,4 +80,4 @@ class MaskOpts(volumeopts.ImageOpts):
         self.threshold.xhi  = self.dataMax + dMinDistance 
         self.setConstraint('threshold', 'minDistance', dMinDistance)
 
-        volumeopts.ImageOpts.__init__(self, overlay, *args, **kwargs)
+        volumeopts.Nifti1Opts.__init__(self, overlay, *args, **kwargs)
diff --git a/fsl/fsleyes/displaycontext/modelopts.py b/fsl/fsleyes/displaycontext/modelopts.py
index d9b8dfc05fbeb20bb58698179cc186f70ecb7cf8..184bc6ad9b1e6e46c2c104b907fdeae60631646c 100644
--- a/fsl/fsleyes/displaycontext/modelopts.py
+++ b/fsl/fsleyes/displaycontext/modelopts.py
@@ -62,7 +62,7 @@ class ModelOpts(fsldisplay.DisplayOpts):
     """
 
     
-    coordSpace = copy.copy(volumeopts.ImageOpts.transform)
+    coordSpace = copy.copy(volumeopts.Nifti1Opts.transform)
     """If :attr:`refImage` is not ``None``, this property defines the
     reference image coordinate space in whihc the model coordinates are
     defined (i.e. voxels, scaled voxels, or world coordinates).
@@ -193,8 +193,8 @@ class ModelOpts(fsldisplay.DisplayOpts):
 
         This method is called whenever the :attr:`refImage` or
         :attr:`coordSpace` properties change and, if a ``refImage`` is
-        specified, whenever the :attr:`.ImageOpts.transform` or
-        :attr:`.ImageOpts.customXform` properties change.
+        specified, whenever the :attr:`.Nifti1Opts.transform` or
+        :attr:`.Nifti1Opts.customXform` properties change.
 
         :arg refImage:    Reference image to use to calculate the coordinates.
                           If ``-1`` the :attr:`refImage` is used (``-1`` is
@@ -205,13 +205,13 @@ class ModelOpts(fsldisplay.DisplayOpts):
                           :attr:`coordSpace` is used.
         
         :arg transform:   Transform to use - if ``None``, and a ``refImage`` is
-                          defined, the :attr:`.ImageOpts.transform` value is
+                          defined, the :attr:`.Nifti1Opts.transform` value is
                           used.
         
         :arg customXform: Custom transform to use (if
                           ``transform=custom``). If ``None``, and a
                           ``refImage`` is defined, the
-                          :attr:`.ImageOpts.customXform` value is used.
+                          :attr:`.Nifti1Opts.customXform` value is used.
         """
 
         if refImage   is -1:   refImage   = self.refImage
@@ -237,8 +237,8 @@ class ModelOpts(fsldisplay.DisplayOpts):
 
 
     def __transformChanged(self, value, valid, ctx, name):
-        """Called when the :attr:`.ImageOpts.transfrom` or
-        :attr:`.ImageOpts.customXform` properties of the current
+        """Called when the :attr:`.Nifti1Opts.transfrom` or
+        :attr:`.Nifti1Opts.customXform` properties of the current
         :attr:`refImage` change. Calls :meth:`__updateBounds`.
         """
 
@@ -274,7 +274,7 @@ class ModelOpts(fsldisplay.DisplayOpts):
 
         If a new reference image has been specified, removes listeners from
         the old one (if necessary), and adds listeners to the
-        :attr:`.ImageOptstransform` and :attr:`.ImageOpts.customXform`
+        :attr:`.Nifti1Opts.transform` and :attr:`.Nifti1Opts.customXform`
         properties associated with the new image. Calls
         :meth:`__updateBounds`.
         """
diff --git a/fsl/fsleyes/displaycontext/vectoropts.py b/fsl/fsleyes/displaycontext/vectoropts.py
index 2f318375e645982859fba89553bbbf2646923ebe..6311eeca81918f0bd6a199b8f7609fd7a8b5464e 100644
--- a/fsl/fsleyes/displaycontext/vectoropts.py
+++ b/fsl/fsleyes/displaycontext/vectoropts.py
@@ -18,7 +18,7 @@ import fsl.data.image as fslimage
 import                   volumeopts
 
 
-class VectorOpts(volumeopts.ImageOpts):
+class VectorOpts(volumeopts.Nifti1Opts):
     """The ``VectorOpts`` class is the base class for :class:`LineVectorOpts`,
     :class:`RGBVectorOpts`, and :class:`.TensorOpts`. It contains display
     settings which are common to each of them.
@@ -67,11 +67,11 @@ class VectorOpts(volumeopts.ImageOpts):
     
     def __init__(self, *args, **kwargs):
         """Create a ``VectorOpts`` instance for the given image.  All
-        arguments are passed through to the :class:`.ImageOpts`
+        arguments are passed through to the :class:`.Nifti1Opts`
         constructor.
         """
         
-        volumeopts.ImageOpts.__init__(self, *args, **kwargs)
+        volumeopts.Nifti1Opts.__init__(self, *args, **kwargs)
 
         self.overlayList.addListener('overlays',
                                      self.name,
@@ -82,7 +82,7 @@ class VectorOpts(volumeopts.ImageOpts):
 
     def destroy(self):
         """Removes some property listeners, and calls the
-        :meth:`.ImageOpts.destroy` method.
+        :meth:`.Nifti1Opts.destroy` method.
         """
         self.overlayList.removeListener('overlays', self.name)
 
@@ -90,7 +90,7 @@ class VectorOpts(volumeopts.ImageOpts):
             display = self.displayCtx.getDisplay(overlay)
             display.removeListener('name', self.name)
 
-        volumeopts.ImageOpts.destroy(self)
+        volumeopts.Nifti1Opts.destroy(self)
 
         
     def __overlayListChanged(self, *a):
diff --git a/fsl/fsleyes/displaycontext/volumeopts.py b/fsl/fsleyes/displaycontext/volumeopts.py
index 599bce8b9bc4ab89c32a9bc660eb2441e6dbc6a4..b164f7b4316e6f58116c8df1cdc08e913de351a1 100644
--- a/fsl/fsleyes/displaycontext/volumeopts.py
+++ b/fsl/fsleyes/displaycontext/volumeopts.py
@@ -4,7 +4,7 @@
 #
 # Author: Paul McCarthy <pauldmccarthy@gmail.com>
 #
-"""This module defines the :class:`ImageOpts` and :class:`VolumeOpts` classes.
+"""This module defines the :class:`Nifti1Opts` and :class:`VolumeOpts` classes.
 
 
 .. _volumeopts-coordinate-systems:
@@ -15,7 +15,7 @@ An important note on coordinate systems
 
 
 *FSLeyes* displays all overlays in a single coordinate system, referred
-throughout as the *display coordinate system*. However, :class:`.Image`
+throughout as the *display coordinate system*. However, :class:`.Nifti1`
 overlays can potentially be displayed in one of three coordinate systems:
 
 
@@ -33,14 +33,14 @@ overlays can potentially be displayed in one of three coordinate systems:
  ====================== ====================================================
 
 
-The :attr:`ImageOpts.transform` property controls how the image data is
+The :attr:`Nifti1Opts.transform` property controls how the image data is
 transformed into the display coordinate system. It allows any of the above
 spaces to be specified (as ``id``, ``pixdim`` or ``affine``` respectively),
 and also allows a ``custom`` transformation to be specified (see the
 :attr:`customXform` property).
 
 
-Regardless of the space in which the ``Image`` is displayed , the
+Regardless of the space in which the ``Nifti1`` is displayed , the
 voxel-to-display space transformation assumes that integer voxel coordinates
 correspond to the centre of the voxel in the display coordinate system. In
 other words, a voxel at location::
@@ -54,7 +54,7 @@ the space::
     [x-0.5 - x+0.5, y-0.5 - y+0.5, z-0.5 - z+0.5]
 
 
-For example, if the :attr:`ImageOpts.transform` property is set to ``id``, the
+For example, if the :attr:`Nifti1Opts.transform` property is set to ``id``, the
 voxel::
 
     [2, 3, 4]
@@ -85,12 +85,12 @@ import display                as fsldisplay
 log = logging.getLogger(__name__)
 
 
-class ImageOpts(fsldisplay.DisplayOpts):
-    """The ``ImageOpts`` class describes how an :class:`.Image` overlay
+class Nifti1Opts(fsldisplay.DisplayOpts):
+    """The ``Nifti1Opts`` class describes how a :class:`.Nifti1` overlay
     should be displayed.
 
     
-    ``ImageOpts`` is the base class for a number of :class:`.DisplayOpts`
+    ``Nifti1Opts`` is the base class for a number of :class:`.DisplayOpts`
     sub-classes - it contains display options which are common to all overlay
     types that represent a NIFTI1 image.
     """
@@ -127,7 +127,7 @@ class ImageOpts(fsldisplay.DisplayOpts):
 
  
     def __init__(self, *args, **kwargs):
-        """Create an ``ImageOpts`` instance.
+        """Create a ``Nifti1Opts`` instance.
 
         All arguments are passed through to the :class:`.DisplayOpts`
         constructor.
@@ -391,8 +391,8 @@ class ImageOpts(fsldisplay.DisplayOpts):
     
     def getVoxel(self):
         """Calculates and returns the voxel coordinates corresponding to the
-        current :attr:`.DisplayContext.location` for the :class:`.Image`
-        associated with this ``ImageOpts`` instance.
+        current :attr:`.DisplayContext.location` for the :class:`.Nifti1`
+        associated with this ``Nifti1Opts`` instance.
 
         Returns ``None`` if the current location is outside of the image
         bounds.
@@ -418,8 +418,8 @@ class ImageOpts(fsldisplay.DisplayOpts):
     def displayToStandardCoordinates(self, coords):
         """Overrides :meth:`.DisplayOpts.displayToStandardCoordinates`.
         Transforms the given display system coordinates into the world
-        coordinates of the :class:`.Image` associated with this
-        ``ImageOpts`` instance.
+        coordinates of the :class:`.Nifti1` associated with this
+        ``Nifti1Opts`` instance.
         """
         return self.transformCoords(coords, 'display', 'world')
 
@@ -427,13 +427,13 @@ class ImageOpts(fsldisplay.DisplayOpts):
     def standardToDisplayCoordinates(self, coords):
         """Overrides :meth:`.DisplayOpts.standardToDisplayCoordinates`.
         Transforms the given coordinates (assumed to be in the world
-        coordinate system of the ``Image`` associated with this ``ImageOpts``
+        coordinate system of the ``Nifti1`` associated with this ``Nifti1Opts``
         instance) into the display coordinate system.
         """ 
         return self.transformCoords(coords, 'world', 'display')
 
 
-class VolumeOpts(ImageOpts):
+class VolumeOpts(Nifti1Opts):
     """The ``VolumeOpts`` class defines options for displaying :class:`.Image`
     instances as regular 3D volumes.
 
@@ -590,12 +590,12 @@ class VolumeOpts(ImageOpts):
         self.setConstraint('displayRange',  'minDistance', dMinDistance)
         self.setConstraint('clippingRange', 'minDistance', dMinDistance)
 
-        ImageOpts.__init__(self,
-                           overlay,
-                           display,
-                           overlayList,
-                           displayCtx,
-                           **kwargs)
+        Nifti1Opts.__init__(self,
+                            overlay,
+                            display,
+                            overlayList,
+                            displayCtx,
+                            **kwargs)
 
         # The displayRange property of every child VolumeOpts
         # instance is linked to the corresponding 
@@ -646,7 +646,7 @@ class VolumeOpts(ImageOpts):
 
 
     def destroy(self):
-        """Removes property listeners, and calls the :meth:`ImageOpts.destroy`
+        """Removes property listeners, and calls the :meth:`Nifti1Opts.destroy`
         method.
         """
 
@@ -662,7 +662,7 @@ class VolumeOpts(ImageOpts):
                              display,
                              display.getSyncPropertyName('contrast'))
 
-        ImageOpts.destroy(self)
+        Nifti1Opts.destroy(self)
 
 
     def __toggleListeners(self, enable=True):
diff --git a/fsl/fsleyes/fsleyes_parseargs.py b/fsl/fsleyes/fsleyes_parseargs.py
index 35f0f6fbe998f45b706e1ea016d1a1aca173ac0e..a4d98a98b58a69a91e9305b0b150f23fbfbfcf19 100644
--- a/fsl/fsleyes/fsleyes_parseargs.py
+++ b/fsl/fsleyes/fsleyes_parseargs.py
@@ -187,7 +187,7 @@ OPTIONS = td.TypeDict({
                         'alpha',
                         'brightness',
                         'contrast'],
-    'ImageOpts'      : ['transform',
+    'Nifti1Opts'     : ['transform',
                         'resolution',
                         'volume'],
     'VolumeOpts'     : ['cmap',
@@ -236,7 +236,7 @@ GROUPNAMES = td.TypeDict({
     'LightBoxOpts'   : 'LightBox display options',
     
     'Display'        : 'Overlay display options',
-    'ImageOpts'      : 'Options for NIFTI images',
+    'Nifti1Opts'     : 'Options for NIFTI images',
     'VolumeOpts'     : 'Volume options',
     'MaskOpts'       : 'Mask options',
     'VectorOpts'     : 'Vector options',
@@ -323,9 +323,9 @@ ARGUMENTS = td.TypeDict({
     'Display.brightness'    : ('b',  'brightness'),
     'Display.contrast'      : ('c',  'contrast'),
 
-    'ImageOpts.resolution'    : ('r',  'resolution'),
-    'ImageOpts.transform'     : ('tf', 'transform'),
-    'ImageOpts.volume'        : ('vl', 'volume'),
+    'Nifti1Opts.resolution'   : ('r',  'resolution'),
+    'Nifti1Opts.transform'    : ('tf', 'transform'),
+    'Nifti1Opts.volume'       : ('vl', 'volume'),
 
     'VolumeOpts.displayRange'   : ('dr', 'displayRange'),
     'VolumeOpts.interpolation'  : ('in', 'interp'),
@@ -428,9 +428,9 @@ HELP = td.TypeDict({
     'Display.brightness'    : 'Brightness',
     'Display.contrast'      : 'Contrast',
 
-    'ImageOpts.resolution' : 'Resolution',
-    'ImageOpts.transform'  : 'Transformation',
-    'ImageOpts.volume'     : 'Volume',
+    'Nifti1Opts.resolution' : 'Resolution',
+    'Nifti1Opts.transform'  : 'Transformation',
+    'Nifti1Opts.volume'     : 'Volume',
 
     'VolumeOpts.displayRange'   : 'Display range',
     'VolumeOpts.clippingRange'  : 'Clipping range',
@@ -687,7 +687,7 @@ def _configOverlayParser(ovlParser):
     """
 
     Display        = fsldisplay.Display
-    ImageOpts      = fsldisplay.ImageOpts
+    Nifti1Opts     = fsldisplay.Nifti1Opts
     VolumeOpts     = fsldisplay.VolumeOpts
     VectorOpts     = fsldisplay.VectorOpts
     RGBVectorOpts  = fsldisplay.RGBVectorOpts
@@ -698,7 +698,7 @@ def _configOverlayParser(ovlParser):
     
     dispParser  = ovlParser.add_argument_group(GROUPNAMES[    Display],
                                                GROUPDESCS.get(Display))
-    imgParser   = ovlParser.add_argument_group(GROUPNAMES[ImageOpts])
+    imgParser   = ovlParser.add_argument_group(GROUPNAMES[Nifti1Opts])
     volParser   = ovlParser.add_argument_group(GROUPNAMES[VolumeOpts])
     vecParser   = ovlParser.add_argument_group(GROUPNAMES[VectorOpts])
     lvParser    = ovlParser.add_argument_group(GROUPNAMES[LineVectorOpts])
@@ -708,7 +708,7 @@ def _configOverlayParser(ovlParser):
     labelParser = ovlParser.add_argument_group(GROUPNAMES[LabelOpts])
 
     targets = [(Display,        dispParser),
-               (ImageOpts,      imgParser),
+               (Nifti1Opts,     imgParser),
                (VolumeOpts,     volParser),
                (VectorOpts,     vecParser),
                (LineVectorOpts, lvParser),
diff --git a/fsl/fsleyes/gl/gllinevector.py b/fsl/fsleyes/gl/gllinevector.py
index d9c834a0e144956f3cb103c354acfd7ac77bd53c..ef416c710c427210a153cd8ad565361875f90fa2 100644
--- a/fsl/fsleyes/gl/gllinevector.py
+++ b/fsl/fsleyes/gl/gllinevector.py
@@ -251,7 +251,7 @@ class GLLineVertices(object):
 
         .. note:: The vertex/texture coordinate generation takes into
                   account the current value of the
-                  :attr:`.ImageOpts.resolution` property of the
+                  :attr:`.Nifti1Opts.resolution` property of the
                   :class:`.LineVectorOpts` instance; if this is set to
                   something other than the image resolution, the
                   sub-sampled starting indices and steps are stored
diff --git a/fsl/fsleyes/gl/globject.py b/fsl/fsleyes/gl/globject.py
index 4eb8aacb38c0315371e8c5fd8ad5caebff928f05..6bbf1c059d69fa5448bf460a883116fc8b0e51de 100644
--- a/fsl/fsleyes/gl/globject.py
+++ b/fsl/fsleyes/gl/globject.py
@@ -329,7 +329,7 @@ class GLImageObject(GLObject):
                         associated with the ``image``.
         ``displayOpts`` A reference to the :class:`.DisplayOpts` instance,
                         containing overlay type-specific display options. This
-                        is assumed to be a sub-class of :class:`.ImageOpts`.
+                        is assumed to be a sub-class of :class:`.Nifti1Opts`.
         =============== =======================================================
 
         :arg image:   The :class:`.Nifti1` instance
diff --git a/fsl/fsleyes/gl/glvector.py b/fsl/fsleyes/gl/glvector.py
index 7a905fa1bd65537c9a57a4061318c20a183bf8d7..6f6cdd0de8487d798b56d0ba107a69ea9f30a009 100644
--- a/fsl/fsleyes/gl/glvector.py
+++ b/fsl/fsleyes/gl/glvector.py
@@ -99,6 +99,7 @@ class GLVector(globject.GLImageObject):
         self.yColourTexture = textures.ColourMapTexture('{}_y'.format(name))
         self.zColourTexture = textures.ColourMapTexture('{}_z'.format(name))
         self.modImage       = None
+        self.modOpts        = None
         self.modTexture     = None
         self.imageTexture   = None
         self.prefilter      = prefilter
@@ -128,6 +129,7 @@ class GLVector(globject.GLImageObject):
         self.imageTexture = None
         self.modTexture   = None
         self.modImage     = None
+        self.modOpts      = None
 
         globject.GLImageObject.destroy(self)
 
@@ -286,12 +288,14 @@ class GLVector(globject.GLImageObject):
 
     def registerModulateImage(self):
         """Called when the :attr:`.VectorOpts.modulate` property changes.
-        Registers a listener with the :attr:`.ImageOpts.volume` property
+        Registers a listener with the :attr:`.Nifti1Opts.volume` property
         of the modulate image, so the modulate texture can be updated when
         the image volume changes.
         """
         
         modImage = self.displayOpts.modulate
+
+        self.modOpts = None
         
         if modImage is None or modImage == 'none': self.modImage = None
         else:                                      self.modImage = modImage
@@ -299,31 +303,30 @@ class GLVector(globject.GLImageObject):
         if self.modImage is None:
             return
 
-        modOpts = self.displayOpts.displayCtx.getOpts(modImage) 
+        self.modOpts = self.displayOpts.displayCtx.getOpts(modImage) 
 
         def volumeChange(*a):
             
-            self.modTexture.set(volume=modOpts.volume)
+            self.modTexture.set(volume=self.modOpts.volume)
             self.refreshModulateTexture()
             self.onUpdate()
 
-        modOpts.addListener('volume', self.name, volumeChange, weak=False) 
+        self.modOpts.addListener('volume', self.name, volumeChange, weak=False) 
 
     
     def deregisterModulateImage(self):
         """Called when the :attr:`.VectorOpts.modulate` property changes.
-        Deregisters the :attr:`.ImageOpts.volume` listener that was
+        Deregisters the :attr:`.Nifti1Opts.volume` listener that was
         registered in :meth:`registerModulateImage`.
         """ 
 
         if self.modImage is None:
             return
 
-        modOpts = self.displayOpts.displayCtx.getOpts(self.modImage) 
-
-        modOpts.removeListener('volume', self.name)
+        self.modOpts.removeListener('volume', self.name)
 
         self.modImage = None
+        self.modOpts  = None
 
             
     def refreshModulateTexture(self):
@@ -338,18 +341,17 @@ class GLVector(globject.GLImageObject):
         if self.modTexture is not None:
             glresources.delete(self.modTexture.getTextureName())
 
-        modImage = self.displayOpts.modulate
+        modImage = self.modImage
+        modOpts  = self.modOpts
 
         if modImage is None or modImage == 'none':
             textureData = np.zeros((5, 5, 5), dtype=np.uint8)
             textureData[:] = 255
             modImage   = fslimage.Image(textureData)
-            modOpts    = None
             norm       = False
             
         else:
-            modOpts = self.displayOpts.displayCtx.getOpts(modImage)
-            norm    = True
+            norm = True
 
         texName = '{}_{}_{}_modulate'.format(
             type(self).__name__, id(self.image), id(modImage))
diff --git a/fsl/fsleyes/gl/slicecanvas.py b/fsl/fsleyes/gl/slicecanvas.py
index fb3ef0f12e48d336c35527e265f5649b91f9b0db..05541fd8635f1676bb1eeabde110d1bc57dc64dc 100644
--- a/fsl/fsleyes/gl/slicecanvas.py
+++ b/fsl/fsleyes/gl/slicecanvas.py
@@ -82,7 +82,7 @@ class SliceCanvas(props.HasProperties):
     The :attr:`resolutionLimit` property controls the highest resolution at
     which :class:`.Image` overlays are displayed on the ``SliceCanvas``. A
     higher value will result in faster rendering performance. When this
-    property is changed, the :attr:`.ImageOpts.resolution` property for every
+    property is changed, the :attr:`.Nifti1Opts.resolution` property for every
     :class:`.Image` overlay is updated.
 
 
@@ -580,7 +580,7 @@ class SliceCanvas(props.HasProperties):
     def __resolutionLimitChange(self, *a):
         """Called when the :attr:`resolutionLimit` property changes.
 
-        Updates the :attr:`.ImageOpts.resolution` of all :class:`.Image`
+        Updates the :attr:`.Nifti1Opts.resolution` of all :class:`.Nifti1`
         overlays in the overlay list.  Whenever the resolution of an
         overlay is changed, its old value is saved, so it can be restored
         later on when possible.
@@ -594,7 +594,7 @@ class SliceCanvas(props.HasProperties):
 
             # No support for non-volumetric overlay 
             # types yet (or maybe ever?)
-            if not isinstance(opts, fsldisplay.ImageOpts):
+            if not isinstance(opts, fsldisplay.Nifti1Opts):
                 continue
             
             currRes = opts.resolution
@@ -648,7 +648,7 @@ class SliceCanvas(props.HasProperties):
                         
 
     def __overlayResolutionChanged(self, value, valid, opts, name):
-        """Called when the :attr:`.ImageOpts.resolution` property for any
+        """Called when the :attr:`.Nifti1Opts.resolution` property for any
         :class:`.Image` overlay changes. Clears the saved resolution for
         the overlay if necessary (see :meth:`__resolutionLimitChange`).
         """
diff --git a/fsl/fsleyes/plotting/powerspectrumseries.py b/fsl/fsleyes/plotting/powerspectrumseries.py
index 8fcbe2fd08c96f9ac5e211c84dcb75dcae415cdb..fa8aefdbe795fe142214e66506d2ba9dfb77845f 100644
--- a/fsl/fsleyes/plotting/powerspectrumseries.py
+++ b/fsl/fsleyes/plotting/powerspectrumseries.py
@@ -149,7 +149,7 @@ class VoxelPowerSpectrumSeries(PowerSpectrumSeries):
 class MelodicPowerSpectrumSeries(PowerSpectrumSeries):
     """The ``MelodicPowerSpectrumSeries`` class encapsulates the power spectrum
     of the time course for a single component of a :class:`.MelodicImage`. The
-    component is dictated by the :attr:`.ImageOpts.volume` property.
+    component is dictated by the :attr:`.Nifti1Opts.volume` property.
     """
 
     
@@ -179,7 +179,7 @@ class MelodicPowerSpectrumSeries(PowerSpectrumSeries):
 
     def getData(self):
         """Returns the power spectrum for the current component of the
-        :class:`.MelodicImage`, as defined by the :attr:`.ImageOpts.volume`
+        :class:`.MelodicImage`, as defined by the :attr:`.Nifti1Opts.volume`
         property.
         """
 
diff --git a/fsl/fsleyes/plotting/timeseries.py b/fsl/fsleyes/plotting/timeseries.py
index e39b5d27009171d7c8846f80f78e91c27711e03e..f06ed3633fed735c18578d73c764e338b4f9aa74 100644
--- a/fsl/fsleyes/plotting/timeseries.py
+++ b/fsl/fsleyes/plotting/timeseries.py
@@ -729,7 +729,7 @@ class MelodicTimeSeries(TimeSeries):
     """A :class:`.TimeSeries` class which encapsulates the time course for
     one component of a :class:`.MelodicImage`. The :meth:`getData` method
     returns the time course of the component specified by the current
-    :class:`.ImageOpts.volume`.
+    :class:`.Nifti1Opts.volume`.
     """
 
     def __init__(self, tsPanel, overlay, displayCtx):
@@ -746,7 +746,7 @@ class MelodicTimeSeries(TimeSeries):
 
     def getComponent(self):
         """Returns the index (starting from 0) of the current Melodic
-        component, as dictated by the :class:`.ImageOpts.volume` property.
+        component, as dictated by the :class:`.Nifti1Opts.volume` property.
         """
         opts = self.displayCtx.getOpts(self.overlay)
         return opts.volume 
diff --git a/fsl/fsleyes/profiles/orthoviewprofile.py b/fsl/fsleyes/profiles/orthoviewprofile.py
index 6c4b8849b41c5686a5364b406d1f305a9c4229c6..55a13ba6166bab8ddc26b677a3c96d85a0c60886 100644
--- a/fsl/fsleyes/profiles/orthoviewprofile.py
+++ b/fsl/fsleyes/profiles/orthoviewprofile.py
@@ -152,9 +152,9 @@ class OrthoViewProfile(profiles.Profile):
         values, one per display space axis, which specify the distance that
         a navigation operation should move the display.
 
-        If the currently selected overlay is an :class:`.Image` instance, the
+        If the currently selected overlay is an :class:`.Nifti1` instance, the
         distance that a navigation operation should shift the display will
-        differ depending on the value of the :attr:`.ImageOpts.transform`
+        differ depending on the value of the :attr:`.Nifti1Opts.transform`
         property. For example, if ``transform`` is ``id``, the display should
         be moved by one unit (which corresponds to one voxel). But if the
         ``transform`` is ``pixdim``, the display should be moved by one pixdim
diff --git a/fsl/fsleyes/tooltips.py b/fsl/fsleyes/tooltips.py
index 674becd8e8ee22494da8b8d7529b0b6cdb317ca8..de98df739e96cf8f8e4bc5c5fa8d76409435dbd1 100644
--- a/fsl/fsleyes/tooltips.py
+++ b/fsl/fsleyes/tooltips.py
@@ -56,16 +56,16 @@ properties = TypeDict({
 
     # Overlay DisplayOpts
 
-    'ImageOpts.volume'     : 'The volume number (for 4D images).',
-    'ImageOpts.resolution' : 'Spatial display resolution, in mm.',
-    'ImageOpts.transform'  : 'The affine transformation matrix to apply '
-                             'to this image. You can choose to display '
-                             'the image without any transformation (as if '
-                             'the image voxels are 1mm isotropic); or you '
-                             'can choose to scale the voxels by the pixdim '
-                             'values in the NIFTI header; or you can choose '
-                             'to apply the affine transformation as defined '
-                             'in the NIFTI header.',
+    'Nifti1Opts.volume'     : 'The volume number (for 4D images).',
+    'Nifti1Opts.resolution' : 'Spatial display resolution, in mm.',
+    'Nifti1Opts.transform'  : 'The affine transformation matrix to apply '
+                              'to this image. You can choose to display '
+                              'the image without any transformation (as if '
+                              'the image voxels are 1mm isotropic); or you '
+                              'can choose to scale the voxels by the pixdim '
+                              'values in the NIFTI header; or you can choose '
+                              'to apply the affine transformation as defined '
+                              'in the NIFTI header.',
 
     'VolumeOpts.displayRange'    : 'Data display range - the low value '
                                    'corresponds to the low colour, and the '
diff --git a/fsl/fsleyes/views/canvaspanel.py b/fsl/fsleyes/views/canvaspanel.py
index 10823a2a0d50d2dc1aea0a1a52465a4959dbcc93..313779332d9de0fdd9578fc452bfe39a75a08007 100644
--- a/fsl/fsleyes/views/canvaspanel.py
+++ b/fsl/fsleyes/views/canvaspanel.py
@@ -571,7 +571,7 @@ class CanvasPanel(viewpanel.ViewPanel):
         If the currently selected overlay (see
         :attr:`.DisplayContext.selectedOverlay`) is a 4D :class:`.Image`
         being displayed as a ``volume`` (see the :class:`.VolumeOpts` class),
-        the :attr:`.ImageOpts.volume` property is incremented.
+        the :attr:`.Nifti1Opts.volume` property is incremented.
         """
 
         overlay = self._displayCtx.getSelectedOverlay()
diff --git a/fsl/fsleyes/views/lightboxpanel.py b/fsl/fsleyes/views/lightboxpanel.py
index 9ab54b1b6c75ecb5cc487ddf120574728d8870aa..543f5de7172b155a57da3bcb197caa1d66e09d19 100644
--- a/fsl/fsleyes/views/lightboxpanel.py
+++ b/fsl/fsleyes/views/lightboxpanel.py
@@ -233,10 +233,10 @@ class LightBoxPanel(canvaspanel.CanvasPanel):
     def __selectedOverlayChanged(self, *a):
         """Called when the :attr:`.DisplayContext.selectedOverlay` changes.
 
-        If the currently selected overlay is an :class:`.Image` instance, or
+        If the currently selected overlay is a :class:`.Nifti1` instance, or
         has an associated reference image (see
         :meth:`.DisplayOpts.getReferenceImage`), a listener is registered on
-        the reference image :attr:`.ImageOpts.transform` property, so that the
+        the reference image :attr:`.Nifti1Opts.transform` property, so that the
         :meth:`__transformChanged` method will be called when it changes.
         """
 
@@ -265,7 +265,7 @@ class LightBoxPanel(canvaspanel.CanvasPanel):
 
 
     def __transformChanged(self, *a):
-        """Called when the :attr:`.ImageOpts.transform` property for the
+        """Called when the :attr:`.Nifti1Opts.transform` property for the
         reference image of the currently selected overlay changes.
 
         Updates the :attr:`.LightBoxOpts.sliceSpacing` and
diff --git a/fsl/fsleyes/views/timeseriespanel.py b/fsl/fsleyes/views/timeseriespanel.py
index 4bcf9475886fb3c41f079bb5911cf6eb1dcc74a3..dde4ece00d06acd3781cdc225d853b026c900286 100644
--- a/fsl/fsleyes/views/timeseriespanel.py
+++ b/fsl/fsleyes/views/timeseriespanel.py
@@ -95,7 +95,7 @@ class TimeSeriesPanel(plotpanel.OverlayPlotPanel):
     The ``TimeSeriesPanel`` also has some functionality for
     :class:`.MelodicImage` overlays - a :class:`.MelodicTimeSeries` instance
     is used to plot the component time courses for the current component (as
-    defined by the :attr:`.ImageOpts.volume` property).
+    defined by the :attr:`.Nifti1Opts.volume` property).
     """