|
30 | 30 | from nipype.pipeline import engine as pe |
31 | 31 |
|
32 | 32 | from .... import data |
33 | | -from ..syn import init_syn_sdc_wf, init_syn_preprocessing_wf, _adjust_zooms, _set_dtype, _mm2vox |
| 33 | +from ..syn import ( |
| 34 | + init_syn_sdc_wf, |
| 35 | + init_syn_preprocessing_wf, |
| 36 | + _adjust_zooms, |
| 37 | + _set_dtype, |
| 38 | + _mm2vox, |
| 39 | +) |
34 | 40 |
|
35 | 41 |
|
36 | 42 | @pytest.mark.veryslow |
@@ -260,25 +266,54 @@ def test_ensure_dtype(in_dtype, out_dtype, tmpdir): |
260 | 266 | assert out_file == f"{in_dtype}_{out_dtype}.nii.gz" |
261 | 267 |
|
262 | 268 |
|
263 | | -def test_mm2vox(tmp_path): |
264 | | - img = nb.Nifti1Image(np.zeros((10, 10, 10)), np.diag((2, 3, 4, 1))) |
265 | | - img_file = tmp_path / "test.nii.gz" |
266 | | - img.to_filename(img_file) |
| 269 | +def axcodes2aff(axcodes): |
| 270 | + """Return an affine matrix from axis codes.""" |
| 271 | + return nb.orientations.inv_ornt_aff( |
| 272 | + nb.orientations.ornt_transform( |
| 273 | + nb.orientations.axcodes2ornt("RAS"), |
| 274 | + nb.orientations.axcodes2ornt(axcodes), |
| 275 | + ), |
| 276 | + (10, 10, 10), |
| 277 | + ) |
267 | 278 |
|
268 | | - config = json.loads(data.load.readable("sd_syn.json").read_text()) |
269 | 279 |
|
270 | | - params = config['transform_parameters'] |
271 | | - mm_values = np.array([level[2] for level in params]) |
| 280 | +@pytest.mark.parametrize( |
| 281 | + ("fixed_ornt", "moving_ornt", "ijk", "index"), |
| 282 | + [ |
| 283 | + ("RAS", "RAS", "i", 0), |
| 284 | + ("RAS", "RAS", "j", 1), |
| 285 | + ("RAS", "RAS", "k", 2), |
| 286 | + ("RAS", "PSL", "i", 1), |
| 287 | + ("RAS", "PSL", "j", 2), |
| 288 | + ("RAS", "PSL", "k", 0), |
| 289 | + ("PSL", "RAS", "i", 2), |
| 290 | + ("PSL", "RAS", "j", 0), |
| 291 | + ("PSL", "RAS", "k", 1), |
| 292 | + ], |
| 293 | +) |
| 294 | +def test_mm2vox(tmp_path, fixed_ornt, moving_ornt, ijk, index): |
| 295 | + fixed_path = tmp_path / "fixed.nii.gz" |
| 296 | + moving_path = tmp_path / "moving.nii.gz" |
| 297 | + |
| 298 | + # Use separate zooms to make identifying the conversion easier |
| 299 | + fixed_aff = np.diag((2, 3, 4, 1)) |
| 300 | + nb.save( |
| 301 | + nb.Nifti1Image(np.zeros((10, 10, 10)), axcodes2aff(fixed_ornt) @ fixed_aff), |
| 302 | + fixed_path, |
| 303 | + ) |
| 304 | + nb.save( |
| 305 | + nb.Nifti1Image(np.zeros((10, 10, 10)), axcodes2aff(moving_ornt)), |
| 306 | + moving_path, |
| 307 | + ) |
272 | 308 |
|
273 | | - vox_params_i = _mm2vox(str(img_file), 'i', config) |
274 | | - vox_values_i = [level[2] for level in vox_params_i] |
275 | | - assert [mm_level[:2] == vox_level[:2] for mm_level, vox_level in zip(params, vox_params_i)] |
276 | | - assert np.array_equal(vox_values_i, mm_values / 2) |
| 309 | + config = json.loads(data.load.readable("sd_syn.json").read_text()) |
277 | 310 |
|
278 | | - vox_params_j = _mm2vox(str(img_file), 'j', config) |
279 | | - vox_values_j = [level[2] for level in vox_params_j] |
280 | | - assert np.array_equal(vox_values_j, mm_values / 3) |
| 311 | + params = config["transform_parameters"] |
| 312 | + mm_values = np.array([level[2] for level in params]) |
281 | 313 |
|
282 | | - vox_params_k = _mm2vox(str(img_file), 'k', config) |
283 | | - vox_values_k = [level[2] for level in vox_params_k] |
284 | | - assert np.array_equal(vox_values_k, mm_values / 4) |
| 314 | + vox_params = _mm2vox(str(moving_path), str(fixed_path), ijk, config) |
| 315 | + vox_values = [level[2] for level in vox_params] |
| 316 | + assert [ |
| 317 | + mm_level[:2] == vox_level[:2] for mm_level, vox_level in zip(params, vox_params) |
| 318 | + ] |
| 319 | + assert np.array_equal(vox_values, mm_values / [2, 3, 4][index]) |
0 commit comments