[030aeb]: / tests / core / test_registration.py

Download this file

132 lines (108 with data), 4.0 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import multiprocessing as mp
import os
import shutil
import unittest
from functools import partial
import numpy as np
import dosma.file_constants as fc
from dosma.core.med_volume import MedicalVolume
from dosma.core.orientation import to_affine
from dosma.core.registration import apply_warp, register
from .. import util
def _generate_translated_vols(n=3):
"""Generate mock data that is translated diagonally by 1 pixel."""
mvs = []
affine = to_affine(("SI", "AP"), (0.3, 0.3, 0.5))
for offset in range(n):
arr = np.zeros((250, 250, 10))
arr[15 + offset : 35 + offset, 15 + offset : 35 + offset] = 1
mvs.append(MedicalVolume(arr, affine))
return mvs
class TestRegister(util.TempPathMixin):
@unittest.skipIf(not util.is_elastix_available(), "elastix is not available")
def test_multiprocessing(self):
mvs = _generate_translated_vols()
data_dir = os.path.join(self.data_dirpath, "test-register-mp")
out_path = os.path.join(data_dir, "expected")
_, expected = register(
mvs[0],
mvs[1:],
fc.ELASTIX_AFFINE_PARAMS_FILE,
out_path,
num_workers=0,
num_threads=2,
return_volumes=True,
rtype=tuple,
show_pbar=True,
)
out_path = os.path.join(data_dir, "out")
_, out = register(
mvs[0],
mvs[1:],
fc.ELASTIX_AFFINE_PARAMS_FILE,
out_path,
num_workers=util.num_workers(),
num_threads=2,
return_volumes=True,
rtype=tuple,
show_pbar=True,
)
for vol, exp in zip(out, expected):
assert np.allclose(vol.volume, exp.volume)
shutil.rmtree(data_dir)
def test_complex(self):
mvs = _generate_translated_vols()
mask = mvs[0]._partial_clone(volume=np.ones(mvs[0].shape))
data_dir = os.path.join(self.data_dirpath, "test-register-complex-sequential-moving-masks")
out_path = os.path.join(data_dir, "expected")
_ = register(
mvs[0],
mvs[1:],
[fc.ELASTIX_AFFINE_PARAMS_FILE, fc.ELASTIX_AFFINE_PARAMS_FILE],
out_path,
target_mask=mask,
use_mask=[True, True],
sequential=True,
num_workers=0,
num_threads=2,
return_volumes=True,
rtype=tuple,
show_pbar=True,
)
shutil.rmtree(data_dir)
class TestApplyWarp(util.TempPathMixin):
@unittest.skipIf(not util.is_elastix_available(), "elastix is not available")
def test_multiprocessing(self):
"""Verify that multiprocessing compatible with apply_warp."""
# Generate viable transform file.
mvs = _generate_translated_vols(n=4)
out_path = os.path.join(self.data_dirpath, "test-apply-warp")
out, _ = register(
mvs[0],
mvs[1],
fc.ELASTIX_AFFINE_PARAMS_FILE,
out_path,
num_workers=util.num_workers(),
num_threads=2,
return_volumes=False,
rtype=tuple,
)
vols = mvs[2:]
# Single process (main thread)
expected = []
for v in vols:
expected.append(apply_warp(v, out_registration=out[0]))
# Multiple process (within apply warp)
num_workers = min(len(vols), util.num_workers())
outputs = apply_warp(vols, out_registration=out[0], num_workers=num_workers)
for mv_out, exp in zip(outputs, expected):
assert np.allclose(mv_out.volume, exp.volume)
# Multiple process
func = partial(apply_warp, out_registration=out[0])
with mp.Pool(num_workers) as p:
outputs = p.map(func, vols)
for mv_out, exp in zip(outputs, expected):
assert np.allclose(mv_out.volume, exp.volume)
shutil.rmtree(out_path)
if __name__ == "__main__":
unittest.main()