|
40 | 40 | @pytest.mark.parametrize("testnum", range(100))
|
41 | 41 | def test_bsplines(tmp_path, testnum):
|
42 | 42 | """Test idempotency of B-Splines interpolation + approximation."""
|
43 |
| - targetshape = (10, 12, 9) |
| 43 | + targetshape = (50, 50, 30) |
44 | 44 |
|
45 | 45 | # Generate an oblique affine matrix for the target - it will be a common case.
|
46 | 46 | targetaff = nb.affines.from_matvec(
|
47 |
| - nb.eulerangles.euler2mat(x=0.9, y=0.001, z=0.001) @ np.diag((2, 3, 4)), |
| 47 | + nb.eulerangles.euler2mat(x=-0.9, y=0.001, z=0.001) @ np.diag((2, 2, 2.4)), |
48 | 48 | )
|
49 | 49 |
|
50 | 50 | # Intendedly mis-centered (exercise we may not have volume-centered NIfTIs)
|
51 | 51 | targetaff[:3, 3] = nb.affines.apply_affine(
|
52 | 52 | targetaff, 0.5 * (np.array(targetshape) - 3)
|
53 | 53 | )
|
54 | 54 |
|
| 55 | + mask = np.zeros(targetshape) |
| 56 | + mask[10:-10, 10:-10, 6:-6] = 1 |
55 | 57 | # Generate some target grid
|
56 |
| - targetnii = nb.Nifti1Image(np.ones(targetshape), targetaff, None) |
57 |
| - targetnii.to_filename(tmp_path / "target.nii.gz") |
| 58 | + targetnii = nb.Nifti1Image(mask, targetaff, None) |
| 59 | + targetnii.header.set_qform(targetaff, code=1) |
| 60 | + targetnii.header.set_sform(targetaff, code=1) |
| 61 | + targetnii.to_filename(tmp_path / "mask.nii.gz") |
58 | 62 |
|
59 | 63 | # Generate random coefficients
|
60 |
| - gridnii = bspline_grid(targetnii, control_zooms_mm=(4, 6, 8)) |
61 |
| - coeff = (rng.random(size=gridnii.shape) - 0.5) * 500 |
| 64 | + gridnii = bspline_grid(targetnii, control_zooms_mm=(40, 40, 16)) |
| 65 | + coeff = (rng.standard_normal(size=gridnii.shape)) * 100 |
62 | 66 | coeffnii = nb.Nifti1Image(coeff.astype("float32"), gridnii.affine, gridnii.header)
|
| 67 | + coeffnii.header["cal_max"] = np.abs(coeff).max() |
| 68 | + coeffnii.header["cal_min"] = -coeffnii.header["cal_max"] |
| 69 | + coeffnii.header.set_qform(gridnii.affine, code=1) |
| 70 | + coeffnii.header.set_sform(gridnii.affine, code=1) |
63 | 71 | coeffnii.to_filename(tmp_path / "coeffs.nii.gz")
|
64 | 72 |
|
65 | 73 | os.chdir(tmp_path)
|
66 | 74 | # Check that we can interpolate the coefficients on a target
|
67 | 75 | test1 = ApplyCoeffsField(
|
68 |
| - in_data=str(tmp_path / "target.nii.gz"), |
| 76 | + in_data=str(tmp_path / "mask.nii.gz"), |
69 | 77 | in_coeff=str(tmp_path / "coeffs.nii.gz"),
|
70 | 78 | pe_dir="j-",
|
71 | 79 | ro_time=1.0,
|
72 | 80 | ).run()
|
73 | 81 |
|
| 82 | + fieldnii = nb.load(test1.outputs.out_field) |
| 83 | + fielddata = fieldnii.get_fdata() |
| 84 | + fielddata -= np.median(fielddata) |
| 85 | + fielddata = 200 * fielddata / np.abs(fielddata).max() |
| 86 | + |
| 87 | + fieldnii.header["cal_max"] = np.abs(fielddata).max() |
| 88 | + fieldnii.header["cal_min"] = -fieldnii.header["cal_max"] |
| 89 | + fieldnii.header.set_qform(targetaff, code=1) |
| 90 | + fieldnii.header.set_sform(targetaff, code=1) |
| 91 | + |
| 92 | + nb.Nifti1Image(fielddata, targetaff, fieldnii.header).to_filename( |
| 93 | + tmp_path / "testfield.nii.gz", |
| 94 | + ) |
| 95 | + |
74 | 96 | # Approximate the interpolated target
|
75 | 97 | test2 = BSplineApprox(
|
76 |
| - in_data=test1.outputs.out_field, |
77 |
| - bs_spacing=[(4, 6, 8)], |
| 98 | + in_data=str(tmp_path / "testfield.nii.gz"), |
| 99 | + # in_mask=str(tmp_path / "mask.nii.gz"), |
| 100 | + bs_spacing=[(40, 40, 16)], |
78 | 101 | zooms_min=0,
|
79 | 102 | recenter=False,
|
80 | 103 | ridge_alpha=1e-4,
|
|
0 commit comments