fsl.data.imagewrapper

This module provides the ImageWrapper class, which can be used to manage data access to nibabel NIFTI images.

Note

This module is deprecated - it is being moved to the FSLeyes project, and will be removed in a future version of fslpy.

Terminology

There are some confusing terms used in this module, so it may be useful to get their definitions straight:

  • Coverage: The portion of an image that has been covered in the data

    range calculation. The ImageWrapper keeps track of the coverage for individual volumes within a 4D image (or slices in a 3D image).

  • Slice: Portion of the image data which is being accessed. A slice

    comprises either a tuple of slice objects (or integers), or a sequence of (low, high) tuples, specifying the index range into each image dimension that is covered by the slice.

  • Expansion: A sequence of (low, high) tuples, specifying an

    index range into each image dimension, that is used to expand the coverage of an image, based on a given set of slices.

  • Fancy slice: Any object which is used to slice an array, and is not

    an int, slice, or Ellipsis, or sequence of these.

class fsl.data.imagewrapper.ImageWrapper(*args, **kwargs)[source]

Bases: Notifier

The ImageWrapper class is a convenience class which manages data access to nibabel NIFTI images. The ImageWrapper class can be used to:

  • Control whether the image is loaded into memory, or kept on disk

  • Incrementally update the known image data range, as more image data is read in.

In memory or on disk?

The image data will be kept on disk, and accessed through the nibabel.Nifti1Image.dataobj (or nibabel.Nifti2Image.dataobj) array proxy, if:

If any of these conditions do not hold, the image data will be loaded into memory and accessed directly.

Image dimensionality

The ImageWrapper abstracts away trailing image dimensions of length 1. This means that if the header for a NIFTI image specifies that the image has four dimensions, but the fourth dimension is of length 1, you do not need to worry about indexing that fourth dimension. However, all NIFTI images will be presented as having at least three dimensions, so if your image header specifies a third dimension of length 1, you will still need provide an index of 0 for that dimensions, for all data accesses.

Data access

The ImageWrapper can be indexed in one of two ways:

  • With basic numpy-like multi-dimensional array slicing (with step sizes of 1)

  • With boolean array indexing, where the boolean/mask array has the same shape as the image data.

See https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html for more details on numpy indexing.

Data range

In order to avoid the computational overhead of calculating the image data range (its minimum/maximum values) when an image is first loaded in, an ImageWrapper incrementally updates the known image data range as data is accessed. The ImageWrapper keeps track of the image data coverage, the portion of the image which has already been considered in the data range calculation. When data from a region of the image not in the coverage is accessed, the coverage is expanded to include this region. The coverage is always expanded in a rectilinear manner, i.e. the coverage is always rectangular for a 2D image, or cuboid for a 3D image.

For a 4D image, the ImageWrapper internally maintains a separate coverage and known data range for each 3D volume within the image. For a 3D image, separate coverages and data ranges are stored for each 2D slice.

The ImageWrapper implements the Notifier interface. Listeners can register to be notified whenever the known image data range is updated. The data range can be accessed via the dataRange property.

The ImageWrapper class uses the following functions (also defined in this module) to keep track of the portion of the image that has currently been included in the data range calculation:

isValidFancySliceObj

Deprecated - moved to fsl.data.image.

canonicalSliceObj

Deprecated - moved to fsl.data.image.

sliceObjToSliceTuple

Deprecated - the imagewrapper has been moved to FSLeyes.

sliceTupleToSliceObj

Deprecated - the imagewrapper has been moved to FSLeyes.

sliceCovered

Deprecated - the imagewrapper has been moved to FSLeyes.

calcExpansion

Deprecated - the imagewrapper has been moved to FSLeyes.

adjustCoverage

Deprecated - the imagewrapper has been moved to FSLeyes.

__init__(image, name=None, loadData=False, dataRange=None, threaded=False)[source]

Create an ImageWrapper.

Parameters:
  • image – A nibabel.Nifti1Image or nibabel.Nifti2Image.

  • name – A name for this ImageWrapper, solely used for debug log messages.

  • loadData – If True, the image data is loaded into memory. Otherwise it is kept on disk (and data access is performed through the nibabel.Nifti1Image.dataobj array proxy).

  • dataRange – A tuple containing the initial (min, max) data range to use. See the reset() method for important information about this parameter.

  • threaded – If True, the data range is updated on a TaskThread. Otherwise (the default), the data range is updated directly on reads/writes.

__del__()[source]

If this ImageWrapper was created with threaded=True, the TaskThread is stopped.

getTaskThread()[source]

If this ImageWrapper was created with threaded=True, this method returns the TaskThread that is used for running data range calculation tasks. Otherwise, this method returns False.

reset(dataRange=None)[source]

Reset the internal state and known data range of this ImageWrapper.

Parameters:

dataRange – A tuple containing the initial (min, max) data range to use.

Note

The dataRange parameter is intended for situations where the image data range is known in advance (e.g. it was calculated earlier, and the image is being re-loaded). If a dataRange is passed in, it will not be overwritten by any range calculated from the data, unless the calculated data range is wider than the provided dataRange.

property dataRange

Returns the currently known data range as a tuple of (min, max) values.

property covered

Returns True if this ImageWrapper has read the entire image data, False otherwise.

property shape

Returns the shape that the image data is presented as. This is the same as the underlying image shape, but with trailing dimensions of length 1 removed, and at least three dimensions.

coverage(vol)[source]

Returns the current image data coverage for the specified volume (for a 4D image, slice for a 3D image, or vector for a 2D images).

Parameters:

vol – Index of the volume/slice/vector to return the coverage for.

Returns:

The coverage for the specified volume, as a numpy array of shape (nd, 2), where nd is the number of dimensions in the volume.

Note

If the specified volume is not covered, the returned array will contain np.nan values.

loadData()[source]

Forces all of the image data to be loaded into memory.

Note

This method will be called by __init__() if its loadData parameter is True. It will also be called on all write operations (see __setitem__()).

property dataIsLoaded

Return true if the image data has been loaded into memory, False otherwise.

__getData(sliceobj, isTuple=False)

Retrieves the image data at the location specified by sliceobj.

Parameters:
  • sliceobj – Something which can be used to slice an array, or a sequence of (low, high) index pairs.

  • isTuple – Set to True if sliceobj is a sequence of (low, high) index pairs.

__imageIsCovered()

Returns True if all portions of the image have been covered in the data range calculation, False otherwise.

__expandCoverage(slices)

Expands the current image data range and coverage to encompass the given slices.

__updateDataRangeOnRead(slices, data)

Called by __getitem__(). Calculates the minimum/maximum values of the given data (which has been extracted from the portion of the image specified by slices), and updates the known data range of the image.

Parameters:
  • slices – A tuple of tuples, each tuple being a (low, high) index pair, one for each dimension in the image.

  • data – The image data at the given slices (as a numpy array).

__updateDataRangeOnWrite(slices, data)

Called by __setitem__(). Assumes that the image data has been changed (the data at slices has been replaced with data. Updates the image data coverage, and known data range accordingly.

Parameters:
  • slices – A tuple of tuples, each tuple being a (low, high) index pair, one for each dimension in the image.

  • data – The image data at the given slices (as a numpy array).

__getitem__(sliceobj)[source]

Returns the image data for the given sliceobj, and updates the known image data range if necessary.

Parameters:

sliceobj – Something which can slice the image data.

__setitem__(sliceobj, values)[source]

Writes the given values to the image at the given sliceobj.

Parameters:
  • sliceobj – Something which can be used to slice the array.

  • values – Data to write to the image.

Note

Modifying image data will cause the entire image to be loaded into memory.

__annotations__ = {}
__module__ = 'fsl.data.imagewrapper'
fsl.data.imagewrapper.isValidFancySliceObj(sliceobj, shape)[source]

Deprecated - moved to fsl.data.image.

fsl.data.imagewrapper.canonicalSliceObj(sliceobj, shape)[source]

Deprecated - moved to fsl.data.image.

fsl.data.imagewrapper.expectedShape(sliceobj, shape)[source]

Deprecated - moved to fsl.data.image.

fsl.data.imagewrapper.sliceObjToSliceTuple(sliceobj, shape)[source]

Deprecated - the imagewrapper has been moved to FSLeyes.

Turns an array slice object into a tuple of (low, high) index pairs, one pair for each dimension in the given shape

Parameters:
  • sliceobj – Something which can be used to slice an array of shape shape.

  • shape – Shape of the array being sliced.

fsl.data.imagewrapper.sliceTupleToSliceObj(slices)[source]

Deprecated - the imagewrapper has been moved to FSLeyes.

Turns a sequence of (low, high) index pairs into a tuple of array slice objects.

Parameters:

slices – A sequence of (low, high) index pairs.

fsl.data.imagewrapper.adjustCoverage(oldCoverage, slices)[source]

Deprecated - the imagewrapper has been moved to FSLeyes.

Adjusts/expands the given oldCoverage so that it covers the given set of slices.

Parameters:
  • oldCoverage – A numpy array of shape (2, n) containing the (low, high) index pairs for n dimensions of a single slice/volume in the image.

  • slices – A sequence of (low, high) index pairs. If slices contains more dimensions than are specified in oldCoverage, the trailing dimensions are ignored.

Returns:

A numpy array containing the adjusted/expanded coverage.

fsl.data.imagewrapper.OVERLAP_ALL = 0

Indicates that the slice is wholly contained within the coverage. This is a return code for the sliceOverlap() function.

fsl.data.imagewrapper.OVERLAP_SOME = 1

Indicates that the slice partially overlaps with the coverage. This is a return code for the sliceOverlap() function.

fsl.data.imagewrapper.OVERLAP_NONE = 2

Indicates that the slice does not overlap with the coverage. This is a return code for the sliceOverlap() function.

fsl.data.imagewrapper.sliceOverlap(slices, coverage)[source]

Deprecated - the imagewrapper has been moved to FSLeyes.

Determines whether the given slices overlap with the given coverage.

Parameters:
  • slices – A sequence of (low, high) index pairs, assumed to cover all image dimensions.

  • coverage – A numpy array of shape (2, nd, nv) (where nd is the number of dimensions being covered, and nv is the number of volumes (or vectors/slices) in the image, which contains the (low, high) index pairs describing the current image coverage.

Returns:

One of the following codes:

OVERLAP_ALL OVERLAP_SOME OVERLAP_NONE

fsl.data.imagewrapper.sliceCovered(slices, coverage)[source]

Deprecated - the imagewrapper has been moved to FSLeyes.

Returns True if the portion of the image data calculated by the given slices` has already been calculated, ``False otherwise.

Parameters:
  • slices – A sequence of (low, high) index pairs, assumed to cover all image dimensions.

  • coverage – A numpy array of shape (2, nd, nv) (where nd is the number of dimensions being covered, and nv is the number of volumes (or vectors/slices) in the image, which contains the (low, high) index pairs describing the current image coverage.

fsl.data.imagewrapper.calcExpansion(slices, coverage)[source]

Deprecated - the imagewrapper has been moved to FSLeyes.

Calculates a series of expansion slices, which can be used to expand the given coverage so that it includes the given slices.

Parameters:
  • slices – Slices that the coverage needs to be expanded to cover.

  • coverage – Current image coverage.

Returns:

A list of volume indices, and a corresponding list of expansions.

fsl.data.imagewrapper.collapseExpansions(expansions, numDims)[source]

Deprecated - the imagewrapper has been moved to FSLeyes.

Scans through the given list of expansions (each assumed to pertain to a single 3D image), and combines any which cover the same image area, and cover adjacent volumes.

Args expansions:

A list of expansion slices - see calcExpansions().

Args numDims:

Number of dimensions covered by each expansion, not including the volume dimension (i.e. 3 for a 4D image).

Returns:

A list of expansions, with equivalent expansions that cover adjacent images collapsed down.

Note

For one expansion exp in the expansions list, this function assumes that the range at exp[numDims] contains the image to which exp pertains (i.e. exp[numDims] == (vol, vol + 1)).