fsl.data.imagewrapper¶
This module provides the ImageWrapper class, which can be used
to manage data access to nibabel NIFTI images.
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
ImageWrapperkeeps 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
sliceobjects (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 anindex 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, orEllipsis, or sequence of these.
-
class
fsl.data.imagewrapper.ImageWrapper(*args, **kwargs)[source]¶ Bases:
fsl.utils.notifier.NotifierThe
ImageWrapperclass is a convenience class which manages data access tonibabelNIFTI images. TheImageWrapperclass 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(ornibabel.Nifti2Image.dataobj) array proxy, if:The
loadDataparameter to__init__()isFalse.The
loadData()method never gets called.The image data is not modified (via
__setitem__().
If any of these conditions do not hold, the image data will be loaded into memory and accessed directly.
Image dimensionality
The
ImageWrapperabstracts 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
ImageWrappercan 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
ImageWrapperincrementally updates the known image data range as data is accessed. TheImageWrapperkeeps 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
ImageWrapperinternally 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
ImageWrapperimplements theNotifierinterface. Listeners can register to be notified whenever the known image data range is updated. The data range can be accessed via thedataRangeproperty.The
ImageWrapperclass 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:Returns
Trueif the givensliceobjis a valid and fancy slice object.Returns a canonical version of the given
sliceobj.Turns an array slice object into a tuple of (low, high) index pairs, one pair for each dimension in the given shape
Turns a sequence of (low, high) index pairs into a tuple of array
sliceobjects.Returns
Trueif the portion of the image data calculated by the givenslices` has already been calculated, ``Falseotherwise.Calculates a series of expansion slices, which can be used to expand the given
coverageso that it includes the givenslices.Adjusts/expands the given
oldCoverageso that it covers the given set ofslices.-
__init__(image, name=None, loadData=False, dataRange=None, threaded=False)[source]¶ Create an
ImageWrapper.- Parameters
image – A
nibabel.Nifti1Imageornibabel.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 thenibabel.Nifti1Image.dataobjarray proxy).dataRange – A tuple containing the initial
(min, max)data range to use. See thereset()method for important information about this parameter.threaded – If
True, the data range is updated on aTaskThread. Otherwise (the default), the data range is updated directly on reads/writes.
-
__del__()[source]¶ If this
ImageWrapperwas created withthreaded=True, theTaskThreadis stopped.
-
getTaskThread()[source]¶ If this
ImageWrapperwas created withthreaded=True, this method returns theTaskThreadthat is used for running data range calculation tasks. Otherwise, this method returnsFalse.
-
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
dataRangeparameter 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 adataRangeis passed in, it will not be overwritten by any range calculated from the data, unless the calculated data range is wider than the provideddataRange.
-
property
dataRange¶ Returns the currently known data range as a tuple of
(min, max)values.
-
property
covered¶ Returns
Trueif thisImageWrapperhas read the entire image data,Falseotherwise.
-
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
numpyarray of shape(nd, 2), wherendis the number of dimensions in the volume.
Note
If the specified volume is not covered, the returned array will contain
np.nanvalues.
-
loadData()[source]¶ Forces all of the image data to be loaded into memory.
Note
This method will be called by
__init__()if itsloadDataparameter isTrue. It will also be called on all write operations (see__setitem__()).
-
__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
Trueifsliceobjis a sequence of (low, high) index pairs.
-
__imageIsCovered()¶ Returns
Trueif all portions of the image have been covered in the data range calculation,Falseotherwise.
-
__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 byslices), 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 anumpyarray).
-
__updateDataRangeOnWrite(slices, data)¶ Called by
__setitem__(). Assumes that the image data has been changed (the data atsliceshas been replaced withdata. 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 anumpyarray).
-
__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
valuesto the image at the givensliceobj.- 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.
-
__module__= 'fsl.data.imagewrapper'¶
-
fsl.data.imagewrapper.isValidFancySliceObj(sliceobj, shape)[source]¶ Returns
Trueif the givensliceobjis a valid and fancy slice object.nibabelrefers to slice objects as “fancy” if they comprise anything but tuples of integers and simplesliceobjects. TheImageWrapperclass supports one type of “fancy” slicing, where thesliceobjis a booleannumpyarray of the same shape as the image.This function returns
Trueif the givensliceobjadheres to these requirements,Falseotherwise.
-
fsl.data.imagewrapper.canonicalSliceObj(sliceobj, shape)[source]¶ Returns a canonical version of the given
sliceobj. See thenibabel.fileslice.canonical_slicersfunction.
-
fsl.data.imagewrapper.expectedShape(sliceobj, shape)[source]¶ Given a slice object, and the shape of an array to which that slice object is going to be applied, returns the expected shape of the result.
Note
It is assumed that the
sliceobjhas been passed through thecanonicalSliceObj()function.- Parameters
sliceobj – Something which can be used to slice an array of shape
shape.shape – Shape of the array being sliced.
- Returns
A tuple containing:
Expected number of dimensions of the result
Expected shape of the result (or
Noneifsliceobjis fancy).
-
fsl.data.imagewrapper.sliceObjToSliceTuple(sliceobj, shape)[source]¶ 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]¶ Turns a sequence of (low, high) index pairs into a tuple of array
sliceobjects.- Parameters
slices – A sequence of (low, high) index pairs.
-
fsl.data.imagewrapper.adjustCoverage(oldCoverage, slices)[source]¶ Adjusts/expands the given
oldCoverageso that it covers the given set ofslices.- Parameters
oldCoverage – A
numpyarray of shape(2, n)containing the (low, high) index pairs forndimensions of a single slice/volume in the image.slices – A sequence of (low, high) index pairs. If
slicescontains more dimensions than are specified inoldCoverage, the trailing dimensions are ignored.
- Returns
A
numpyarray 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]¶ Determines whether the given
slicesoverlap with the givencoverage.- Parameters
slices – A sequence of (low, high) index pairs, assumed to cover all image dimensions.
coverage – A
numpyarray of shape(2, nd, nv)(wherendis the number of dimensions being covered, andnvis 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]¶ Returns
Trueif the portion of the image data calculated by the givenslices` has already been calculated, ``Falseotherwise.- Parameters
slices – A sequence of (low, high) index pairs, assumed to cover all image dimensions.
coverage – A
numpyarray of shape(2, nd, nv)(wherendis the number of dimensions being covered, andnvis 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]¶ Calculates a series of expansion slices, which can be used to expand the given
coverageso that it includes the givenslices.- 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]¶ 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
expin theexpansionslist, this function assumes that the range atexp[numDims]contains the image to whichexppertains (i.e.exp[numDims] == (vol, vol + 1)).