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

[MAINT] Use rng fixture for setting up np.random.RandomState() - part 2 #4054

Merged
merged 3 commits into from
Oct 16, 2023
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
30 changes: 12 additions & 18 deletions nilearn/image/tests/test_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
generate_maps,
)
from nilearn._utils.exceptions import DimensionError
from nilearn.conftest import _affine_eye, _shape_4d_default
from nilearn.conftest import _affine_eye, _rng, _shape_4d_default
from nilearn.image import (
binarize_img,
clean_img,
Expand Down Expand Up @@ -82,7 +82,7 @@ def _make_largest_cc_img_test_data():

def _images_to_mean():
"""Return a mixture of 4D and 3D images"""
rng = np.random.RandomState(42)
rng = _rng()

data1 = np.zeros((5, 6, 7))
data2 = rng.uniform(size=(5, 6, 7))
Expand Down Expand Up @@ -437,9 +437,8 @@ def test_mean_img(images_to_mean):
)


def test_mean_img_resample():
def test_mean_img_resample(rng):
# Test resampling in mean_img with a permutation of the axes
rng = np.random.RandomState(42)
data = rng.uniform(size=(5, 6, 7, 40))
affine = np.diag((4, 3, 2, 1))
img = Nifti1Image(data, affine=affine)
Expand All @@ -462,9 +461,7 @@ def test_mean_img_resample():
assert_array_equal(mean_img_with_resampling.affine, target_affine)


def test_swap_img_hemispheres(affine_eye, shape_3d_default):
rng = np.random.RandomState(42)

def test_swap_img_hemispheres(affine_eye, shape_3d_default, rng):
# make sure input image data is not overwritten inside function
data = rng.standard_normal(size=shape_3d_default)
data_img = Nifti1Image(data, affine_eye)
Expand Down Expand Up @@ -531,7 +528,7 @@ def test_index_img_error_4D(affine_eye):
index_img(img_4d, i)


def test_pd_index_img():
def test_pd_index_img(rng):
# confirm indices from pandas dataframes are handled correctly
if "pandas" not in sys.modules:
raise pytest.skip(msg="Pandas not available")
Expand All @@ -540,7 +537,6 @@ def test_pd_index_img():

fourth_dim_size = img_4d.shape[3]

rng = np.random.RandomState(42)
arr = rng.uniform(size=fourth_dim_size) > 0.5
df = pd.DataFrame({"arr": arr})

Expand Down Expand Up @@ -630,16 +626,16 @@ def test_new_img_like():
assert_array_equal(get_data(img_nifti2), get_data(img2_nifti2))


def test_new_img_like_accepts_paths(tmp_path):
def test_new_img_like_accepts_paths(tmp_path, rng):
"""Check that new_img_like can accept instances of pathlib.Path."""
nifti_path = tmp_path / "sample.nii"
assert isinstance(nifti_path, Path)

data = np.random.rand(10, 10, 10)
data = rng.rand(10, 10, 10)
img = Nifti1Image(data, np.eye(4))
nibabel.save(img, nifti_path)

new_data = np.random.rand(10, 10, 10)
new_data = rng.rand(10, 10, 10)
new_img = new_img_like(nifti_path, new_data)
assert new_img.shape == (10, 10, 10)

Expand All @@ -648,12 +644,11 @@ def test_new_img_like_accepts_paths(tmp_path):
assert new_img.shape == (10, 10, 10)


def test_new_img_like_non_iterable_header():
def test_new_img_like_non_iterable_header(rng):
"""
Tests that when an niimg's header is not iterable
& it is set to be copied, an error is not raised.
"""
rng = np.random.RandomState(42)
fake_fmri_data = rng.uniform(size=_shape_4d_default())
fake_affine = rng.uniform(size=(4, 4))
fake_spatial_image = nibabel.spatialimages.SpatialImage(
Expand Down Expand Up @@ -863,8 +858,7 @@ def test_binarize_img(img_4D_rand_eye):
assert_array_equal(img2.dataobj, img3.dataobj)


def test_clean_img(affine_eye, shape_3d_default):
rng = np.random.RandomState(42)
def test_clean_img(affine_eye, shape_3d_default, rng):
data = rng.standard_normal(size=(10, 10, 10, 100)) + 0.5
data_flat = data.T.reshape(100, -1)
data_img = Nifti1Image(data, affine_eye)
Expand Down Expand Up @@ -987,11 +981,11 @@ def test_new_img_like_mgh_image(affine_eye, shape_3d_default):


@pytest.mark.parametrize("image", [MGHImage, AnalyzeImage])
def test_new_img_like_boolean_data(affine_eye, image, shape_3d_default):
def test_new_img_like_boolean_data(affine_eye, image, shape_3d_default, rng):
"""Check defaulting boolean input data to np.uint8 dtype is valid for
encoding with nibabel image classes MGHImage and AnalyzeImage.
"""
data = np.random.randn(*shape_3d_default).astype("uint8")
data = rng.randn(*shape_3d_default).astype("uint8")
in_img = image(dataobj=data, affine=affine_eye)

out_img = new_img_like(in_img, data=in_img.get_fdata() > 0.5)
Expand Down
78 changes: 22 additions & 56 deletions nilearn/image/tests/test_resampling.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

from nilearn import _utils
from nilearn._utils import testing
from nilearn.conftest import _affine_eye
from nilearn.conftest import _affine_eye, _rng
from nilearn.image import get_data
from nilearn.image.image import _pad_array, crop_img
from nilearn.image.resampling import (
Expand All @@ -37,7 +37,7 @@


def _make_resampling_test_data():
rng = np.random.RandomState(42)
rng = _rng()
shape = SHAPE
affine = _affine_eye()
data = rng.randint(0, 10, shape, dtype="int32")
Expand Down Expand Up @@ -68,9 +68,8 @@ def affine():
return np.eye(4)


def test_identity_resample(shape, affine):
def test_identity_resample(shape, affine, rng):
"""Test resampling with an identity affine."""
rng = np.random.RandomState(42)
data = rng.randint(0, 10, shape, dtype="int32")
affine[:3, -1] = 0.5 * np.array(shape[:3])

Expand Down Expand Up @@ -102,14 +101,13 @@ def test_identity_resample(shape, affine):
@pytest.mark.parametrize("endian_type", [">f8", "<f8"])
@pytest.mark.parametrize("interpolation", ["nearest", "linear", "continuous"])
def test_identity_resample_non_native_endians(
shape, affine, endian_type, interpolation
shape, affine, endian_type, interpolation, rng
):
"""Test resampling with an identity affine with non native endians

with big endian data ('>f8')
with little endian data ('<f8')
"""
rng = np.random.RandomState(42)
data = rng.randint(0, 10, shape, dtype="int32")
affine[:3, -1] = 0.5 * np.array(shape[:3])

Expand All @@ -122,9 +120,8 @@ def test_identity_resample_non_native_endians(
assert_almost_equal(data, get_data(rot_img))


def test_downsample(shape, affine):
def test_downsample(shape, affine, rng):
"""Test resampling with a 1/2 down-sampling affine."""
rng = np.random.RandomState(42)
data = rng.random_sample(shape)

rot_img = resample_img(
Expand All @@ -151,7 +148,7 @@ def test_downsample(shape, affine):
@pytest.mark.parametrize("endian_type", [">f8", "<f8"])
@pytest.mark.parametrize("copy_data", [True, False])
def test_downsample_non_native_endian_data(
shape, affine, endian_type, copy_data
shape, affine, endian_type, copy_data, rng
):
"""Test resampling with a 1/2 down-sampling affine with non native endians.

Expand All @@ -161,7 +158,6 @@ def test_downsample_non_native_endian_data(
Big endian data ">f8"
Little endian data "<f8"
"""
rng = np.random.RandomState(42)
data = rng.random_sample(shape)

rot_img = resample_img(
Expand All @@ -187,13 +183,11 @@ def test_downsample_non_native_endian_data(

@pytest.mark.parametrize("shape", [(1, 4, 4), (1, 4, 4, 3)])
@pytest.mark.parametrize("value", [-3.75, 0])
def test_resampling_fill_value(affine, shape, value):
def test_resampling_fill_value(affine, shape, value, rng):
"""Test resampling with a non-zero fill value

Check on 3D and 4D data.
"""
rng = np.random.RandomState(42)

data = rng.uniform(size=shape)

angle = np.pi / 4
Expand Down Expand Up @@ -229,13 +223,11 @@ def test_resampling_fill_value(affine, shape, value):

@pytest.mark.parametrize("shape", [(1, 4, 4), (1, 4, 4, 3)])
@pytest.mark.parametrize("angle", ANGLES_TO_TEST)
def test_resampling_with_affine(affine, shape, angle):
def test_resampling_with_affine(affine, shape, angle, rng):
"""Test resampling with a given rotation part of the affine.

Check on 3D and 4D data.
"""
rng = np.random.RandomState(42)

data = rng.randint(4, size=shape, dtype="int32")
rot = rotation(0, angle)

Expand All @@ -260,9 +252,7 @@ def test_resampling_with_affine(affine, shape, angle):

@pytest.mark.parametrize("shape", [(1, 10, 10), (1, 10, 10, 3)])
@pytest.mark.parametrize("angle", (0, np.pi / 2.0, np.pi, 3 * np.pi / 2.0))
def test_resampling_continuous_with_affine(affine, shape, angle):
rng = np.random.RandomState(42)

def test_resampling_continuous_with_affine(affine, shape, angle, rng):
data = rng.randint(1, 4, size=shape, dtype="int32")
rot = rotation(0, angle)
img = Nifti1Image(data, affine)
Expand Down Expand Up @@ -336,9 +326,7 @@ def test_resampling_copy_has_no_shared_memory(target_shape):
assert_almost_equal(img_r.affine, img.affine)


def test_resampling_warning_s_form(shape):
rng = np.random.RandomState(42)

def test_resampling_warning_s_form(shape, rng):
affine = np.eye(4)

data = rng.randint(0, 10, shape, dtype="int32")
Expand All @@ -349,9 +337,7 @@ def test_resampling_warning_s_form(shape):
resample_img(img_no_sform, target_affine=affine)


def test_resampling_warning_binary_image(affine):
rng = np.random.RandomState(42)

def test_resampling_warning_binary_image(affine, rng):
# Resampling a binary image with continuous or
# linear interpolation should raise a warning.
data_binary = rng.randint(4, size=(1, 4, 4), dtype="int32")
Expand Down Expand Up @@ -622,9 +608,7 @@ def test_resampling_nan_big(affine):
assert_allclose(10, resampled_data[np.isfinite(resampled_data)])


def test_resample_to_img(affine, shape):
rng = np.random.RandomState(42)

def test_resample_to_img(affine, shape, rng):
data = rng.random_sample(shape)

source_affine = affine
Expand Down Expand Up @@ -654,12 +638,10 @@ def test_crop(affine):
assert_equal(get_data(cropped), data)


def test_resample_identify_affine_int_translation(affine):
rng = np.random.RandomState(42)

def test_resample_identify_affine_int_translation(affine, rng):
source_shape = (6, 4, 6)
source_affine = affine
source_affine[:, 3] = np.append(np.random.randint(0, 4, 3), 1)
source_affine[:, 3] = np.append(rng.randint(0, 4, 3), 1)
source_data = rng.random_sample(source_shape)
source_img = Nifti1Image(source_data, source_affine)

Expand Down Expand Up @@ -722,9 +704,7 @@ def test_resample_clip(affine):
assert_array_equal(no_clip_data[not_clip], clip_data[not_clip])


def test_reorder_img(affine):
rng = np.random.RandomState(42)

def test_reorder_img(affine, rng):
# We need to test on a square array, as rotation does not change
# shape, whereas reordering does.
shape = (5, 5, 5, 2, 2)
Expand Down Expand Up @@ -752,9 +732,7 @@ def test_reorder_img(affine):
assert_almost_equal(get_data(reordered_img), data)


def test_reorder_img_with_resample_arg(affine):
rng = np.random.RandomState(42)

def test_reorder_img_with_resample_arg(affine, rng):
shape = (5, 5, 5, 2, 2)
data = rng.uniform(size=shape)
affine = affine
Expand All @@ -773,9 +751,7 @@ def test_reorder_img_with_resample_arg(affine):
assert_array_equal(get_data(reordered_img), get_data(resampled_img))


def test_reorder_img_error_reorder_axis():
rng = np.random.RandomState(42)

def test_reorder_img_error_reorder_axis(rng):
shape = (5, 5, 5, 2, 2)
data = rng.uniform(size=shape)

Expand All @@ -792,9 +768,7 @@ def test_reorder_img_error_reorder_axis():
reorder_img(ref_img)


def test_reorder_img_flipping_axis():
rng = np.random.RandomState(42)

def test_reorder_img_flipping_axis(rng):
shape = (5, 5, 5, 2, 2)

data = rng.uniform(size=shape)
Expand Down Expand Up @@ -822,9 +796,7 @@ def test_reorder_img_flipping_axis():
assert np.all(np.diag(img2.affine) >= 0)


def test_reorder_img_error_interpolation():
rng = np.random.RandomState(42)

def test_reorder_img_error_interpolation(rng):
shape = (5, 5, 5, 2, 2)
data = rng.uniform(size=shape)
affine = np.eye(4)
Expand Down Expand Up @@ -874,9 +846,7 @@ def test_reorder_img_mirror():
)


def test_coord_transform_trivial():
rng = np.random.RandomState(42)

def test_coord_transform_trivial(rng):
sform = np.eye(4)
x = rng.random_sample((10,))
y = rng.random_sample((10,))
Expand Down Expand Up @@ -977,9 +947,7 @@ def test_resampling_with_int64_types_no_crash(affine, dtype):
resample_img(img, target_affine=2.0 * affine)


def test_resample_input(affine, shape):
rng = np.random.RandomState(42)

def test_resample_input(affine, shape, rng):
data = rng.randint(0, 10, shape, dtype="int32")
affine[:3, -1] = 0.5 * np.array(shape[:3])
img = Nifti1Image(data, affine)
Expand All @@ -989,9 +957,7 @@ def test_resample_input(affine, shape):
resample_img(filename, target_affine=affine, interpolation="nearest")


def test_smoke_resampling_non_nifti(affine, shape):
rng = np.random.RandomState(42)

def test_smoke_resampling_non_nifti(affine, shape, rng):
target_affine = 2 * affine
data = rng.randint(0, 10, shape, dtype="int32")
img = MGHImage(data, affine)
Expand Down