Skip to content
Snippets Groups Projects
Commit 0f31c949 authored by Paul McCarthy's avatar Paul McCarthy :mountain_bicyclist:
Browse files

RF: New StatisticAtlas base class, basically the same as the old

ProbabilisticAtlas. The latter now sub-classes the former.
parent 570a239f
No related branches found
No related tags found
No related merge requests found
...@@ -949,15 +949,18 @@ class LabelAtlas(Atlas): ...@@ -949,15 +949,18 @@ class LabelAtlas(Atlas):
return fslimage.Image(arr, name=label.name, header=self.header) return fslimage.Image(arr, name=label.name, header=self.header)
class ProbabilisticAtlas(Atlas): class StatisticAtlas(Atlas):
"""A 4D atlas which contains one volume for each region. """A ``StatisticAtlas`` is a 4D image which contains one volume for
each region in the atlas; each volume contains some statistic value
for the corresponding region.
The ``ProbabilisticAtlas`` provides the :meth`proportions` method, The :class:`ProbabilisticAtlas` is a specialisation of the
which makes looking up region probabilities easy. ``StatisticAtlas``
""" """
def __init__(self, atlasDesc, resolution=None, **kwargs): def __init__(self, atlasDesc, resolution=None, **kwargs):
"""Create a ``ProbabilisticAtlas`` instance. """Create a ``StatisticAtlas`` instance.
:arg atlasDesc: The :class:`AtlasDescription` instance describing :arg atlasDesc: The :class:`AtlasDescription` instance describing
the atlas. the atlas.
...@@ -966,17 +969,18 @@ class ProbabilisticAtlas(Atlas): ...@@ -966,17 +969,18 @@ class ProbabilisticAtlas(Atlas):
""" """
Atlas.__init__(self, atlasDesc, resolution, False, **kwargs) Atlas.__init__(self, atlasDesc, resolution, False, **kwargs)
def get(self, label=None, index=None, value=None, name=None): def get(self, label=None, index=None, value=None, name=None):
""" """Returns the statistic image at the given label.
Returns the probabilistic image for given label
Only one of the arguments should be used to define the label Only one of the arguments should be used to define the label
:arg label: AtlasLabel contained within this atlas :arg label: :class:`AtlasLabel` contained within this atlas
:arg index: index of the label :arg index: index of the label
:arg value: value of the label :arg value: value of the label
:arg name: string of the label :arg name: string of the label
:return: image.Image with the probabilistic mask :return: :class:`.Image` with the statistic values for the
specified label.
""" """
if ((label is not None) + (index is not None) + if ((label is not None) + (index is not None) +
(value is not None) + (name is not None)) != 1: (value is not None) + (name is not None)) != 1:
...@@ -988,7 +992,8 @@ class ProbabilisticAtlas(Atlas): ...@@ -988,7 +992,8 @@ class ProbabilisticAtlas(Atlas):
arr = self[..., label.index] arr = self[..., label.index]
return fslimage.Image(arr, name=label.name, header=self.header) return fslimage.Image(arr, name=label.name, header=self.header)
def proportions(self, location, *args, **kwargs):
def values(self, location, *args, **kwargs):
"""Looks up and returns the proportions of of all regions at the given """Looks up and returns the proportions of of all regions at the given
location. location.
...@@ -1011,13 +1016,13 @@ class ProbabilisticAtlas(Atlas): ...@@ -1011,13 +1016,13 @@ class ProbabilisticAtlas(Atlas):
""" """
if isinstance(location, fslimage.Image): if isinstance(location, fslimage.Image):
return self.maskProportions(location, *args, **kwargs) return self.maskValues(location, *args, **kwargs)
else: else:
return self.coordProportions(location, *args, **kwargs) return self.coordValues(location, *args, **kwargs)
def coordProportions(self, loc, voxel=False): def coordValues(self, loc, voxel=False):
"""Looks up the region probabilities for the given location. """Looks up the region values for the given location.
:arg loc: A sequence of three values, interpreted as atlas :arg loc: A sequence of three values, interpreted as atlas
world or voxel coordinates. world or voxel coordinates.
...@@ -1025,10 +1030,8 @@ class ProbabilisticAtlas(Atlas): ...@@ -1025,10 +1030,8 @@ class ProbabilisticAtlas(Atlas):
:arg voxel: Defaults to ``False``. If ``True``, the ``loc`` :arg voxel: Defaults to ``False``. If ``True``, the ``loc``
argument is interpreted as voxel coordinates. argument is interpreted as voxel coordinates.
:returns: a list of values, one per region, which represent :returns: a list of values, one per region. Returns an empty
the probability of each region for the specified list if the given location is out of bounds.
location. Returns an empty list if the given
location is out of bounds.
""" """
if not voxel: if not voxel:
...@@ -1043,30 +1046,27 @@ class ProbabilisticAtlas(Atlas): ...@@ -1043,30 +1046,27 @@ class ProbabilisticAtlas(Atlas):
loc[2] >= self.shape[2]: loc[2] >= self.shape[2]:
return [] return []
props = self[loc[0], loc[1], loc[2], :] vals = self[loc[0], loc[1], loc[2], :]
# We only return labels for this atlas - # We only return labels for this atlas -
# the underlying image may have more # the underlying image may have more
# volumes than this atlas has labels. # volumes than this atlas has labels.
return [props[l.index] for l in self.desc.labels] return [vals[l.index] for l in self.desc.labels]
def maskProportions(self, mask): def maskValues(self, mask):
"""Looks up the probabilities of all regions in the given ``mask``. """Looks up the average values of all regions in the given ``mask``.
:arg mask: A 3D :class:`.Image`` which is interpreted as a weighted :arg mask: A 3D :class:`.Image`` which is interpreted as a weighted
mask. If the ``mask`` shape does not match that of this mask. If the ``mask`` shape does not match that of this
``ProbabilisticAtlas``, it is resampled using ``StatisticAtlas``, it is resampled using
:meth:`.Image.resample`, with nearest-neighbour :meth:`Atlas.prepareMask`.
interpolation.
:returns: A sequence containing the proportion, within the mask, :returns: A sequence containing the average value, within the mask,
of all regions in the atlas. The proportions are returned as of all regions in the atlas.
values between 0 and 100.
""" """
props = [] avgvals = []
mask = self.prepareMask(mask) mask = self.prepareMask(mask)
boolmask = mask > 0 boolmask = mask > 0
weights = mask[boolmask] weights = mask[boolmask]
...@@ -1079,11 +1079,35 @@ class ProbabilisticAtlas(Atlas): ...@@ -1079,11 +1079,35 @@ class ProbabilisticAtlas(Atlas):
vals = self[..., label.index] vals = self[..., label.index]
vals = vals[boolmask] * weights vals = vals[boolmask] * weights
prop = vals.sum() / weightsum val = vals.sum() / weightsum
props.append(prop) avgvals.append(val)
return props return avgvals
@deprecated.deprecated('2.6.0', '3.0.0', 'Use values instead')
def proportions(self, *args, **kwargs):
"""Deprecated - use :meth:`values` instead. """
return self.values(*args, **kwargs)
@deprecated.deprecated('2.6.0', '3.0.0', 'Use coordValues instead')
def coordProportions(self, *args, **kwargs):
"""Deprecated - use :meth:`coordValues` instead. """
return self.coordValues(*args, **kwargs)
@deprecated.deprecated('2.6.0', '3.0.0', 'Use maskValues instead')
def maskProportions(self, *args, **kwargs):
"""Deprecated - use :meth:`maskValues` instead. """
return self.maskValues(*args, **kwargs)
class ProbabilisticAtlas(StatisticAtlas):
"""A 4D atlas which contains one volume for each region. Each volume
contains probabiliy values for one region, between 0 and 100.
"""
registry = AtlasRegistry() registry = AtlasRegistry()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment