|
22 | 22 | # |
23 | 23 | """Integration tests.""" |
24 | 24 |
|
| 25 | +import hashlib |
25 | 26 | from os import cpu_count |
26 | 27 |
|
27 | 28 | import nibabel as nb |
|
33 | 34 | from nifreeze.model.base import TrivialModel |
34 | 35 | from nifreeze.registration.utils import displacements_within_mask |
35 | 36 |
|
| 37 | +EXPECTED_DWI_MOTION_SHA256 = "3ba55cc3acfd584a7738f9701724e284f54bdf72261bf535b5dae062d7c0c30e" |
36 | 38 |
|
37 | | -def test_proximity_estimator_trivial_model(datadir, tmp_path, atol_mm=0.15): |
38 | | - """Check the proximity of transforms estimated by the estimator with a trivial B0 model.""" |
39 | 39 |
|
40 | | - dwi_motion = DWI.from_filename(datadir / "dmri_data" / "motion_test_data" / "dwi_motion.h5") |
| 40 | +def _sha256sum(path): |
| 41 | + hasher = hashlib.sha256() |
| 42 | + with path.open("rb") as fileobj: |
| 43 | + for chunk in iter(lambda: fileobj.read(1024 * 1024), b""): |
| 44 | + hasher.update(chunk) |
| 45 | + return hasher.hexdigest() |
| 46 | + |
| 47 | + |
| 48 | +def test_proximity_estimator_trivial_model(datadir, tmp_path, p_error=20.0): |
| 49 | + """ |
| 50 | + Check the proximity of transforms estimated by the estimator with a trivial B0 model. |
| 51 | +
|
| 52 | + Parameters |
| 53 | + ---------- |
| 54 | + datadir : pathlib.Path |
| 55 | + Path to the test data directory. |
| 56 | + tmp_path : pathlib.Path |
| 57 | + Path to a temporary directory for test outputs. |
| 58 | + p_error : float, optional |
| 59 | + Acceptable percentage error in the estimated transforms, by default 20.0. |
| 60 | +
|
| 61 | + """ |
| 62 | + |
| 63 | + dwi_motion_path = datadir / "dmri_data" / "motion_test_data" / "dwi_motion.h5" |
| 64 | + assert _sha256sum(dwi_motion_path) == EXPECTED_DWI_MOTION_SHA256, ( |
| 65 | + "Unexpected checksum for dwi_motion.h5" |
| 66 | + ) |
| 67 | + |
| 68 | + dwi_motion = DWI.from_filename(dwi_motion_path) |
41 | 69 | dwi_motion._filepath = tmp_path / "dwi_motion.h5" # Prevent accidental overwriting |
42 | 70 |
|
43 | 71 | ground_truth_affines = ( |
@@ -81,9 +109,23 @@ def test_proximity_estimator_trivial_model(datadir, tmp_path, atol_mm=0.15): |
81 | 109 | ] |
82 | 110 | ) |
83 | 111 |
|
| 112 | + gt_inverse_errors = np.array( |
| 113 | + [ |
| 114 | + displacements_within_mask( |
| 115 | + masknii, # type: ignore |
| 116 | + ~nt.linear.Affine(truth), |
| 117 | + nt.linear.Affine(np.eye(4)), |
| 118 | + ).max() |
| 119 | + for truth in ground_truth_affines # type: ignore |
| 120 | + ] |
| 121 | + ) |
| 122 | + |
| 123 | + error_levels = gt_inverse_errors * p_error * 0.01 |
84 | 124 | masksize = (np.asanyarray(masknii.dataobj) > 0).astype(int).sum() |
85 | | - assert np.all(max_error_mask < atol_mm), ( |
86 | | - f"Some max error exceeds {atol_mm}mm, N={masksize}vox." |
| 125 | + assert np.all(max_error_mask < error_levels), ( |
| 126 | + "Errors per volume [estimated(ground truth) mm]: " |
| 127 | + + ", ".join(f"{e:.2f}({g:.2f})" for e, g in zip(max_error_mask, gt_inverse_errors)) |
| 128 | + + f" (N={masksize} voxels)." |
87 | 129 | ) |
88 | 130 |
|
89 | 131 |
|
|
0 commit comments