Skip to content

Commit

Permalink
Merge branch 'master' into meson
Browse files Browse the repository at this point in the history
  • Loading branch information
skoudoro committed Nov 17, 2023
2 parents a35e01e + bc3adcc commit 5d009be
Show file tree
Hide file tree
Showing 86 changed files with 958 additions and 553 deletions.
3 changes: 3 additions & 0 deletions .codecov.yml
@@ -1,3 +1,6 @@
github_checks:
annotations: false

comment:
layout: "reach, diff, files"
behavior: default
Expand Down
12 changes: 6 additions & 6 deletions dipy/align/streamlinear.py
Expand Up @@ -1042,8 +1042,8 @@ def slr_with_qbx(static, moving,
progressive : boolean, optional
(default True)
rng : RandomState
If None creates RandomState in function.
rng : np.random.Generator
If None creates random generator in function.
num_threads : int, optional
Number of threads to be used for OpenMP parallelization. If None
Expand Down Expand Up @@ -1072,7 +1072,7 @@ def slr_with_qbx(static, moving,
"""
if rng is None:
rng = np.random.RandomState()
rng = np.random.default_rng()

if verbose:
logger.info('Static streamlines size {}'.format(len(static)))
Expand Down Expand Up @@ -1207,8 +1207,8 @@ def groupwise_slr(bundles, x0='affine', tol=0, max_iter=20, qbx_thr=[4],
verbose : bool, optional
If True, logs information. Default: False.
rng : RandomState
If None, creates RandomState in function. Default: None.
rng : np.random.Generator
If None, creates random generator in function. Default: None.
References
----------
Expand All @@ -1233,7 +1233,7 @@ def group_distance(bundles, n_bundle):
return d

if rng is None:
rng = np.random.RandomState()
rng = np.random.default_rng()

metric = JointBundleMinDistanceMetric()

Expand Down
4 changes: 3 additions & 1 deletion dipy/align/streamwarp.py
Expand Up @@ -265,7 +265,9 @@ def bundlewarp_shape_analysis(moving_aligned, deformed_bundle, no_disks=10,
indx = assignment_map(deformed_bundle, deformed_bundle, n)
indx = np.array(indx)

colors = np.random.rand(n, 3)
rng = np.random.default_rng()

colors = rng.random((n, 3))

disks_color = []
for _, ind in enumerate(indx):
Expand Down
8 changes: 5 additions & 3 deletions dipy/align/tests/test_api.py
Expand Up @@ -23,6 +23,7 @@
from dipy.io.stateful_tractogram import StatefulTractogram, Space
from dipy.io.gradients import read_bvals_bvecs
from dipy.io.image import load_nifti
from dipy.testing.decorators import set_random_number_generator


def setup_module():
Expand Down Expand Up @@ -246,11 +247,12 @@ def test_register_dwi_series_and_motion_correction():
npt.assert_array_equal(reg_affines, reg_affines_2)


def test_streamline_registration():
@set_random_number_generator()
def test_streamline_registration(rng):
sl1 = [np.array([[0, 0, 0], [0, 0, 0.5], [0, 0, 1], [0, 0, 1.5]]),
np.array([[0, 0, 0], [0, 0.5, 0.5], [0, 1, 1]])]
affine_mat = np.eye(4)
affine_mat[:3, 3] = np.random.randn(3)
affine_mat[:3, 3] = rng.standard_normal(3)
sl2 = list(transform_tracking_output(sl1, affine_mat))
aligned, matrix = streamline_registration(sl2, sl1)
npt.assert_almost_equal(matrix, np.linalg.inv(affine_mat))
Expand All @@ -259,7 +261,7 @@ def test_streamline_registration():

# We assume the two tracks come from the same space, but it might have
# some affine associated with it:
base_aff = np.eye(4) * np.random.rand()
base_aff = np.eye(4) * rng.random()
base_aff[:3, 3] = np.array([1, 2, 3])
base_aff[3, 3] = 1

Expand Down
4 changes: 2 additions & 2 deletions dipy/align/tests/test_expectmax.py
Expand Up @@ -309,7 +309,7 @@ def test_quantize_positive_2d(rng):
# make sure additive noise doesn't change the quantization result
noise_amplitude = np.min([delta / 4.0, min_positive / 4.0])
sz = np.size(true_quantization)
noise = np.random.ranf(sz).reshape(img_shape) * noise_amplitude
noise = rng.random(sz).reshape(img_shape) * noise_amplitude
noise = noise.astype(floating)
input_image = np.ndarray(img_shape, dtype=floating)
# assign intensities plus noise
Expand Down Expand Up @@ -372,7 +372,7 @@ def test_quantize_positive_3d(rng):
# make sure additive noise doesn't change the quantization result
noise_amplitude = np.min([delta / 4.0, min_positive / 4.0])
sz = np.size(true_quantization)
noise = np.random.ranf(sz).reshape(img_shape) * noise_amplitude
noise = rng.random(sz).reshape(img_shape) * noise_amplitude
noise = noise.astype(floating)
input_image = np.ndarray(img_shape, dtype=floating)
# assign intensities plus noise
Expand Down
22 changes: 13 additions & 9 deletions dipy/align/tests/test_imaffine.py
Expand Up @@ -175,7 +175,8 @@ def test_transform_origins_3d():
assert_array_almost_equal(actual.affine, expected)


def test_affreg_all_transforms():
@set_random_number_generator(202311)
def test_affreg_all_transforms(rng):
# Test affine registration using all transforms with typical settings

# Make sure dictionary entries are processed in the same order regardless
Expand All @@ -198,7 +199,8 @@ def test_affreg_all_transforms():
trans,
factor,
nslices,
1.0)
1.0,
rng=rng)
# Sum of absolute differences
start_sad = np.abs(static - moving).sum()
metric = imaffine.MutualInformationMetric(32, sampling_pc)
Expand Down Expand Up @@ -243,7 +245,8 @@ def test_affreg_all_transforms():
np.zeros_like(smask), np.zeros_like(mmask))


def test_affreg_defaults():
@set_random_number_generator(202311)
def test_affreg_defaults(rng):
# Test all default arguments with an arbitrary transform
# Select an arbitrary transform (all of them are already tested
# in test_affreg_all_transforms)
Expand All @@ -260,7 +263,7 @@ def test_affreg_defaults():
factor = factors[ttype][0]
transform = regtransforms[ttype]
static, moving, static_grid2world, moving_grid2world, smask, mmask, T = \
setup_random_transform(transform, factor, nslices, 1.0)
setup_random_transform(transform, factor, nslices, 1.0, rng=rng)
# Sum of absolute differences
start_sad = np.abs(static - moving).sum()

Expand Down Expand Up @@ -297,7 +300,7 @@ def test_affreg_defaults():
end_sad = np.abs(moving - transformed_inv).sum()
reduction = 1 - end_sad / start_sad
print("%s>>%f" % (ttype, reduction))
assert(reduction > 0.9)
assert(reduction > 0.89)


@set_random_number_generator(2022966)
Expand Down Expand Up @@ -326,7 +329,7 @@ def test_mi_gradient(rng):
start.param_to_matrix(0.25 * rng.standard_normal(nrot))
# Get data (pair of images related to each other by an known transform)
static, moving, static_g2w, moving_g2w, smask, mmask, M = \
setup_random_transform(transform, factor, nslices, 2.0)
setup_random_transform(transform, factor, nslices, 2.0, rng=rng)

# Prepare a MutualInformationMetric instance
mi_metric = imaffine.MutualInformationMetric(32, sampling_proportion)
Expand Down Expand Up @@ -608,10 +611,11 @@ def test_affine_map(rng):
assert_raises(AffineInversionError, AffineMap, mat_large_dim)


def test_MIMetric_invalid_params():
@set_random_number_generator()
def test_MIMetric_invalid_params(rng):
transform = regtransforms[('AFFINE', 3)]
static = np.random.rand(20, 20, 20)
moving = np.random.rand(20, 20, 20)
static = rng.random((20, 20, 20))
moving = rng.random((20, 20, 20))
n = transform.get_number_of_parameters()
sampling_proportion = 0.3
theta_sing = np.zeros(n)
Expand Down
37 changes: 25 additions & 12 deletions dipy/align/tests/test_parzenhist.py
Expand Up @@ -31,7 +31,7 @@
('AFFINE', 3): 0.1}


def create_random_image_pair(sh, nvals, seed):
def create_random_image_pair(sh, nvals, rng=None):
r""" Create a pair of images with an arbitrary, non-uniform joint PDF
Parameters
Expand All @@ -42,6 +42,9 @@ def create_random_image_pair(sh, nvals, seed):
maximum number of different values in the generated 2D images.
The voxel intensities of the returned images will be in
{0, 1, ..., nvals-1}
rng : numpy.random.generator
numpy's random generator. If None, it is set with a random seed.
Default is None
Returns
-------
Expand All @@ -50,7 +53,8 @@ def create_random_image_pair(sh, nvals, seed):
moving : array, shape=sh
second image in the image pair
"""
rng = np.random.default_rng(seed)
if rng is None:
rng = np.random.default_rng()
sz = reduce(mul, sh, 1)
sh = tuple(sh)
static = rng.integers(0, nvals, sz).reshape(sh)
Expand Down Expand Up @@ -173,10 +177,10 @@ def test_parzen_joint_histogram():
assert_equal(index, P.padding + i)


def test_parzen_densities():
@set_random_number_generator(1246592)
def test_parzen_densities(rng):
# Test the computation of the joint intensity distribution
# using a dense and a sparse set of values
seed = 1246592
nbins = 32
nr = 30
nc = 35
Expand All @@ -186,10 +190,10 @@ def test_parzen_densities():
for dim in [2, 3]:
if dim == 2:
shape = (nr, nc)
static, moving = create_random_image_pair(shape, nvals, seed)
static, moving = create_random_image_pair(shape, nvals, rng)
else:
shape = (ns, nr, nc)
static, moving = create_random_image_pair(shape, nvals, seed)
static, moving = create_random_image_pair(shape, nvals, rng)

# Initialize
parzen_hist = ParzenJointHistogram(nbins)
Expand Down Expand Up @@ -257,7 +261,6 @@ def test_parzen_densities():
expected_smarginal_sparse)


@set_random_number_generator(3147702)
def setup_random_transform(transform, rfactor, nslices=45, sigma=1, rng=None):
r""" Creates a pair of images related to each other by an affine transform
Expand All @@ -276,7 +279,14 @@ def setup_random_transform(transform, rfactor, nslices=45, sigma=1, rng=None):
added to the identity parameters to create the random transform
nslices: int
number of slices to be stacked to form the volumes
sigma: float
standard deviation of the gaussian filter
rng: np.random.Generator
numpy's random generator. If None, it is set with a random seed.
Default is None
"""
if rng is None:
rng = np.random.default_rng()
dim = 2 if nslices == 1 else 3
if transform.get_dim() != dim:
raise ValueError("Transform and requested volume have different dims.")
Expand Down Expand Up @@ -316,7 +326,8 @@ def setup_random_transform(transform, rfactor, nslices=45, sigma=1, rng=None):
return static, moving, static_g2w, moving_g2w, smask, mmask, M


def test_joint_pdf_gradients_dense():
@set_random_number_generator(3147702)
def test_joint_pdf_gradients_dense(rng):
# Compare the analytical and numerical (finite differences) gradient of
# the joint distribution (i.e. derivatives of each histogram cell) w.r.t.
# the transform parameters. Since the histograms are discrete partitions
Expand Down Expand Up @@ -351,7 +362,8 @@ def test_joint_pdf_gradients_dense():
theta = transform.get_identity_parameters()

static, moving, static_g2w, moving_g2w, smask, mmask, M = \
setup_random_transform(transform, factor, nslices, 5.0)
setup_random_transform(transform, factor, nslices, 5.0,
rng=rng)
parzen_hist = ParzenJointHistogram(32)
parzen_hist.setup(static, moving, smask, mmask)

Expand Down Expand Up @@ -412,7 +424,8 @@ def test_joint_pdf_gradients_dense():
assert(std_cosine < 0.25)


def test_joint_pdf_gradients_sparse():
@set_random_number_generator(3147702)
def test_joint_pdf_gradients_sparse(rng):
h = 1e-4

# Make sure dictionary entries are processed in the same order regardless
Expand All @@ -435,14 +448,14 @@ def test_joint_pdf_gradients_sparse():
theta = transform.get_identity_parameters()

static, moving, static_g2w, moving_g2w, smask, mmask, M = \
setup_random_transform(transform, factor, nslices, 5.0)
setup_random_transform(transform, factor, nslices, 5.0,
rng=rng)
parzen_hist = ParzenJointHistogram(32)
parzen_hist.setup(static, moving, smask, mmask)

# Sample the fixed-image domain
k = 3
sigma = 0.25
rng = np.random.default_rng(1234)
shape = np.array(static.shape, dtype=np.int32)
samples = sample_domain_regular(k, shape, static_g2w, sigma, rng)
samples = np.array(samples)
Expand Down

0 comments on commit 5d009be

Please sign in to comment.