Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Doc generation under Windows #1915

Merged
merged 19 commits into from Jul 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions dipy/align/bundlemin.pyx
Expand Up @@ -37,8 +37,8 @@ cdef double min_direct_flip_dist(double *a,double *b,
out : double
mininum of direct and flipped average distances

Reference
---------
References
-----------
.. [Garyfallidis12] Garyfallidis E. et al., QuickBundles a method for
tractography simplification, Frontiers in Neuroscience,
vol 6, no 175, 2012.
Expand Down
60 changes: 41 additions & 19 deletions dipy/align/imaffine.py
Expand Up @@ -40,6 +40,7 @@
& Eubank, W. PET-CT image registration in the chest using
free-form deformations. IEEE Transactions on Medical
Imaging, 22(1), 120-8, 2003.

"""

import numpy as np
Expand Down Expand Up @@ -127,6 +128,7 @@ def __init__(self, affine, domain_grid_shape=None, domain_grid2world=None,
the grid-to-world transform associated with the co-domain grid.
If None (the default), then the grid-to-world transform is assumed
to be the identity.

"""
self.set_affine(affine)
self.domain_shape = domain_grid_shape
Expand All @@ -135,20 +137,20 @@ def __init__(self, affine, domain_grid_shape=None, domain_grid2world=None,
self.codomain_grid2world = codomain_grid2world

def get_affine(self):
"""
Returns the value of the transformation, not a reference!
"""Return the value of the transformation, not a reference.

Returns
-------
affine : ndarray
Copy of the transform, not a reference.

"""

# returning a copy to insulate it from changes outside object
return self.affine.copy()

def set_affine(self, affine):
""" Sets the affine transform (operating in physical space)
"""Set the affine transform (operating in physical space).

Also sets `self.affine_inv` - the inverse of `affine`, or None if
there is no inverse.
Expand All @@ -160,6 +162,7 @@ def set_affine(self, affine):
physical space. The domain and co-domain information
remains unchanged. If None, then `self` represents the identity
transformation.

"""

if affine is None:
Expand Down Expand Up @@ -243,7 +246,7 @@ def __format__(self, format_spec):
def _apply_transform(self, image, interp='linear', image_grid2world=None,
sampling_grid_shape=None, sampling_grid2world=None,
resample_only=False, apply_inverse=False):
""" Transforms the input image applying this affine transform
"""Transform the input image applying this affine transform.

This is a generic function to transform images using either this
(direct) transform or its inverse.
Expand Down Expand Up @@ -289,10 +292,12 @@ def _apply_transform(self, image, interp='linear', image_grid2world=None,
transform. Otherwise, the image is transformed from the domain
of this transform to its codomain using the (inverse) affine
transform.

Returns
-------
transformed : array, shape `sampling_grid_shape` or `self.domain_shape`
the transformed image, sampled at the requested grid

"""
# Verify valid interpolation requested
if interp not in _interp_options:
Expand Down Expand Up @@ -355,7 +360,7 @@ def _apply_transform(self, image, interp='linear', image_grid2world=None,
def transform(self, image, interp='linear', image_grid2world=None,
sampling_grid_shape=None, sampling_grid2world=None,
resample_only=False):
""" Transforms the input image from co-domain to domain space
"""Transform the input image from co-domain to domain space.

By default, the transformed image is sampled at a grid defined by
`self.domain_shape` and `self.domain_grid2world`. If such
Expand Down Expand Up @@ -386,11 +391,13 @@ def transform(self, image, interp='linear', image_grid2world=None,
If False (the default) the affine transform is applied normally.
If True, then the affine transform is not applied, and the input
image is just re-sampled on the domain grid of this transform.

Returns
-------
transformed : array, shape `sampling_grid_shape` or
`self.codomain_shape`
the transformed image, sampled at the requested grid

"""
transformed = self._apply_transform(image, interp, image_grid2world,
sampling_grid_shape,
Expand All @@ -402,7 +409,7 @@ def transform(self, image, interp='linear', image_grid2world=None,
def transform_inverse(self, image, interp='linear', image_grid2world=None,
sampling_grid_shape=None, sampling_grid2world=None,
resample_only=False):
""" Transforms the input image from domain to co-domain space
"""Transform the input image from domain to co-domain space.

By default, the transformed image is sampled at a grid defined by
`self.codomain_shape` and `self.codomain_grid2world`. If such
Expand Down Expand Up @@ -433,11 +440,13 @@ def transform_inverse(self, image, interp='linear', image_grid2world=None,
If False (the default) the affine transform is applied normally.
If True, then the affine transform is not applied, and the input
image is just re-sampled on the domain grid of this transform.

Returns
-------
transformed : array, shape `sampling_grid_shape` or
`self.codomain_shape`
the transformed image, sampled at the requested grid

"""
transformed = self._apply_transform(image, interp, image_grid2world,
sampling_grid_shape,
Expand All @@ -450,7 +459,7 @@ def transform_inverse(self, image, interp='linear', image_grid2world=None,
class MutualInformationMetric(object):

def __init__(self, nbins=32, sampling_proportion=None):
r""" Initializes an instance of the Mutual Information metric
r"""Initialize an instance of the Mutual Information metric.

This class implements the methods required by Optimizer to drive the
registration process.
Expand Down Expand Up @@ -479,6 +488,7 @@ def __init__(self, nbins=32, sampling_proportion=None):
voxel to prevent sampling points from being located exactly at voxel
coordinates. When using dense sampling, this random displacement is
not applied.

"""
self.histogram = ParzenJointHistogram(nbins)
self.sampling_proportion = sampling_proportion
Expand All @@ -487,7 +497,7 @@ def __init__(self, nbins=32, sampling_proportion=None):

def setup(self, transform, static, moving, static_grid2world=None,
moving_grid2world=None, starting_affine=None):
r""" Prepares the metric to compute intensity densities and gradients
r"""Prepare the metric to compute intensity densities and gradients.

The histograms will be setup to compute probability densities of
intensities within the minimum and maximum values of `static` and
Expand Down Expand Up @@ -517,6 +527,7 @@ def setup(self, transform, static, moving, static_grid2world=None,
instead of manually transforming the moving image to reduce
interpolation artifacts. The default is None, implying no
pre-alignment is performed.

"""
n = transform.get_number_of_parameters()
self.metric_grad = np.zeros(n, dtype=np.float64)
Expand Down Expand Up @@ -574,7 +585,7 @@ def setup(self, transform, static, moving, static_grid2world=None,
self.histogram.setup(self.static, self.moving)

def _update_histogram(self):
r""" Updates the histogram according to the current affine transform
r"""Update the histogram according to the current affine transform.

The current affine transform is given by `self.affine_map`, which
must be set before calling this method.
Expand All @@ -599,6 +610,7 @@ def _update_histogram(self):
then the intensities are given by the moving imaged linearly
transformed towards the static image by the current affine, which
results in an image of the same shape as the static image.

"""
if self.sampling_proportion is None: # Dense case
static_values = self.static
Expand All @@ -616,7 +628,7 @@ def _update_histogram(self):
return static_values, moving_values

def _update_mutual_information(self, params, update_gradient=True):
r""" Updates marginal and joint distributions and the joint gradient
r"""Update marginal and joint distributions and the joint gradient.

The distributions are updated according to the static and transformed
images. The transformed image is precisely the moving image after
Expand All @@ -635,6 +647,7 @@ def _update_mutual_information(self, params, update_gradient=True):
if True, the gradient of the joint PDF will also be computed,
otherwise, only the marginal and joint PDFs will be computed.
The default is True.

"""
# Get the matrix associated with the `params` parameter vector
current_affine = self.transform.param_to_matrix(params)
Expand Down Expand Up @@ -690,7 +703,7 @@ def _update_mutual_information(self, params, update_gradient=True):
grad)

def distance(self, params):
r""" Numeric value of the negative Mutual Information
r"""Numeric value of the negative Mutual Information.

We need to change the sign so we can use standard minimization
algorithms.
Expand All @@ -708,6 +721,7 @@ def distance(self, params):
the negative mutual information of the input images after
transforming the moving image by the currently set transform
with `params` parameters

"""
try:
self._update_mutual_information(params, False)
Expand All @@ -716,7 +730,7 @@ def distance(self, params):
return -1 * self.metric_val

def gradient(self, params):
r""" Numeric value of the metric's gradient at the given parameters
r"""Numeric value of the metric's gradient at the given parameters.

Parameters
----------
Expand All @@ -729,6 +743,7 @@ def gradient(self, params):
-------
grad : array, shape (n,)
the gradient of the negative Mutual Information

"""
try:
self._update_mutual_information(params, True)
Expand All @@ -737,7 +752,7 @@ def gradient(self, params):
return -1 * self.metric_grad

def distance_and_gradient(self, params):
r""" Numeric value of the metric and its gradient at given parameters
r"""Numeric value of the metric and its gradient at given parameters.

Parameters
----------
Expand All @@ -754,6 +769,7 @@ def distance_and_gradient(self, params):
with `params` parameters
neg_mi_grad : array, shape (n,)
the gradient of the negative Mutual Information

"""
try:
self._update_mutual_information(params, True)
Expand All @@ -773,7 +789,7 @@ def __init__(self,
ss_sigma_factor=None,
options=None,
verbosity=VerbosityLevels.STATUS):
""" Initializes an instance of the AffineRegistration class
"""Initialize an instance of the AffineRegistration class.

Parameters
----------
Expand Down Expand Up @@ -813,6 +829,7 @@ def __init__(self,
options : dict, optional
extra optimization options. The default is None, implying
no extra options are passed to the optimizer.

"""
self.metric = metric

Expand Down Expand Up @@ -862,7 +879,7 @@ def __init__(self,
def _init_optimizer(self, static, moving, transform, params0,
static_grid2world, moving_grid2world,
starting_affine):
r"""Initializes the registration optimizer
r"""Initialize the registration optimizer.

Initializes the optimizer by computing the scale space of the input
images
Expand Down Expand Up @@ -895,6 +912,7 @@ def _init_optimizer(self, static, moving, transform, params0,
array, shape (dim+1, dim+1)
If None:
Start from identity

"""
self.dim = len(static.shape)
self.transform = transform
Expand Down Expand Up @@ -964,7 +982,7 @@ def _init_optimizer(self, static, moving, transform, params0,
def optimize(self, static, moving, transform, params0,
static_grid2world=None, moving_grid2world=None,
starting_affine=None, ret_metric=False):
r""" Starts the optimization process
r""" Start the optimization process.

Parameters
----------
Expand Down Expand Up @@ -1016,6 +1034,7 @@ def optimize(self, static, moving, transform, params0,
the optimal parameters (translation, rotation shear etc.)
fopt : Similarity metric
the value of the function at the optimal parameters.

"""
self._init_optimizer(static, moving, transform, params0,
static_grid2world, moving_grid2world,
Expand Down Expand Up @@ -1117,7 +1136,7 @@ def align_origins(static, static_grid2world,

def transform_centers_of_mass(static, static_grid2world,
moving, moving_grid2world):
r""" Transformation to align the center of mass of the input images
r""" Transformation to align the center of mass of the input images.

Parameters
----------
Expand All @@ -1136,6 +1155,7 @@ def transform_centers_of_mass(static, static_grid2world,
the affine transformation (translation only, in this case) aligning
the center of mass of the moving image towards the one of the static
image

"""
dim = len(static.shape)
if static_grid2world is None:
Expand All @@ -1156,7 +1176,7 @@ def transform_centers_of_mass(static, static_grid2world,

def transform_geometric_centers(static, static_grid2world,
moving, moving_grid2world):
r""" Transformation to align the geometric center of the input images
r""" Transformation to align the geometric center of the input images.

With "geometric center" of a volume we mean the physical coordinates of
its central voxel
Expand All @@ -1178,6 +1198,7 @@ def transform_geometric_centers(static, static_grid2world,
the affine transformation (translation only, in this case) aligning
the geometric center of the moving image towards the one of the static
image

"""
dim = len(static.shape)
if static_grid2world is None:
Expand All @@ -1198,7 +1219,7 @@ def transform_geometric_centers(static, static_grid2world,

def transform_origins(static, static_grid2world,
moving, moving_grid2world):
r""" Transformation to align the origins of the input images
r""" Transformation to align the origins of the input images.

With "origin" of a volume we mean the physical coordinates of
voxel (0,0,0)
Expand All @@ -1220,6 +1241,7 @@ def transform_origins(static, static_grid2world,
the affine transformation (translation only, in this case) aligning
the origin of the moving image towards the one of the static
image

"""
dim = len(static.shape)
if static_grid2world is None:
Expand Down
4 changes: 2 additions & 2 deletions dipy/align/parzenhist.pyx
Expand Up @@ -1308,8 +1308,8 @@ def sample_domain_regular(int k, int[:] shape, double[:, :] grid2world,
samples : array, shape (total_pixels//k, dim)
the matrix whose rows are the sampled points

Example
-------
Examples
--------
>>> from dipy.align.parzenhist import sample_domain_regular
>>> import dipy.align.vector_fields as vf
>>> shape = np.array((10, 10), dtype=np.int32)
Expand Down