def test_ssd_2d_gauss_newton(): r""" Test 2D SyN with SSD metric, Gauss-Newton optimizer Classical Circle-To-C experiment for 2D monomodal registration. We verify that the final registration is of good quality. """ fname_moving = get_fnames('reg_o') fname_static = get_fnames('reg_c') moving = np.load(fname_moving) static = np.load(fname_static) moving = np.array(moving, dtype=floating) static = np.array(static, dtype=floating) moving = (moving - moving.min()) / (moving.max() - moving.min()) static = (static - static.min()) / (static.max() - static.min()) # Create the SSD metric smooth = 4 inner_iter = 5 step_type = 'gauss_newton' similarity_metric = metrics.SSDMetric(2, smooth, inner_iter, step_type) # Configure and run the Optimizer level_iters = [200, 100, 50, 25] step_length = 0.5 opt_tol = 1e-4 inv_iter = 40 inv_tol = 1e-3 ss_sigma_factor = 0.2 optimizer = imwarp.SymmetricDiffeomorphicRegistration( similarity_metric, level_iters, step_length, ss_sigma_factor, opt_tol, inv_iter, inv_tol) # test callback not being called optimizer.INIT_START_CALLED = 0 optimizer.INIT_END_CALLED = 0 optimizer.OPT_START_CALLED = 0 optimizer.OPT_END_CALLED = 0 optimizer.SCALE_START_CALLED = 0 optimizer.SCALE_END_CALLED = 0 optimizer.ITER_START_CALLED = 0 optimizer.ITER_END_CALLED = 0 optimizer.verbosity = VerbosityLevels.DEBUG id = np.eye(3) mapping = optimizer.optimize(static, moving, id, id, id) m = optimizer.get_map() assert_equal(mapping, m) warped = mapping.transform(moving) starting_energy = np.sum((static - moving)**2) final_energy = np.sum((static - warped)**2) reduced = 1.0 - final_energy / starting_energy assert (reduced > 0.9) assert_equal(optimizer.OPT_START_CALLED, 0) assert_equal(optimizer.OPT_END_CALLED, 0) assert_equal(optimizer.SCALE_START_CALLED, 0) assert_equal(optimizer.SCALE_END_CALLED, 0) assert_equal(optimizer.ITER_START_CALLED, 0) assert_equal(optimizer.ITER_END_CALLED, 0)
def test_ssd_3d_gauss_newton(): r''' Register a stack of circles ('cylinder') before and after warping them with a synthetic diffeomorphism. This test is intended to detect regressions only: we saved the energy profile (the sequence of energy values at each iteration) of a working version of SSD in 3D using the Gauss-Newton step, and this test checks that the current energy profile matches the saved one. The validation of the "working version" was done by registering the 18 manually annotated T1 brain MRI database IBSR with each other and computing the jaccard index for all 31 common anatomical regions. ''' moving, static = get_synthetic_warped_circle(35) moving[...,:10] = 0 moving[...,-1:-11:-1] = 0 static[...,:10] = 0 static[...,-1:-11:-1] = 0 #Create the SSD metric smooth = 4 inner_iter = 5 step_type = 'gauss_newton' similarity_metric = metrics.SSDMetric(3, smooth, inner_iter, step_type) #Create the optimizer level_iters = [10, 5] step_length = 0.25 opt_tol = 1e-4 inv_iter = 20 inv_tol = 1e-3 ss_sigma_factor = 0.5 optimizer = imwarp.SymmetricDiffeomorphicRegistration(similarity_metric, level_iters, step_length, ss_sigma_factor, opt_tol, inv_iter, inv_tol) optimizer.verbosity = VerbosityLevels.DEBUG mapping = optimizer.optimize(static, moving, None) m = optimizer.get_map() assert_equal(mapping, m) energy_profile = subsample_profile( optimizer.full_energy_profile, 10) print(energy_profile) if USING_VC_SSE2: expected_profile = \ np.array([348.3204721, 143.480757, 44.30003405, 8.73624842, 3.13227203, 14.70806563, 6.48360268, 23.52491883, 17.25669088, 48.99709064]) elif USING_GCC_SSE2: expected_profile = \ np.array([348.3204721, 143.48075646, 44.30003413, 8.73624841, 3.13227181, 14.70806845, 6.48360884, 23.52499421, 17.25667176, 48.997691]) assert_array_almost_equal(energy_profile, expected_profile, decimal=4)
def test_ssd_3d_gauss_newton(): r''' Register a stack of circles ('cylinder') before and after warping them with a synthetic diffeomorphism. This test is intended to detect regressions only: we saved the energy profile (the sequence of energy values at each iteration) of a working version of SSD in 3D using the Gauss-Newton step, and this test checks that the current energy profile matches the saved one. The validation of the "working version" was done by registering the 18 manually annotated T1 brain MRI database IBSR with each other and computing the jaccard index for all 31 common anatomical regions. ''' moving, static = get_synthetic_warped_circle(35) moving[...,:10] = 0 moving[...,-1:-11:-1] = 0 static[...,:10] = 0 static[...,-1:-11:-1] = 0 #Create the SSD metric smooth = 4 inner_iter = 5 step_type = 'gauss_newton' similarity_metric = metrics.SSDMetric(3, smooth, inner_iter, step_type) #Create the optimizer level_iters = [10, 5] step_length = 0.25 opt_tol = 1e-4 inv_iter = 20 inv_tol = 1e-3 ss_sigma_factor = 0.5 optimizer = imwarp.SymmetricDiffeomorphicRegistration(similarity_metric, level_iters, step_length, ss_sigma_factor, opt_tol, inv_iter, inv_tol) optimizer.verbosity = VerbosityLevels.DEBUG mapping = optimizer.optimize(static, moving, None) m = optimizer.get_map() assert_equal(mapping, m) energy_profile = np.array(optimizer.full_energy_profile) if floating is np.float32: expected_profile = \ np.array([348.32047209927373, 143.49111863234222, 44.328151771258206, 8.759564367010988, 3.1378191742723662, 14.846951961939153, 6.405154727081836, 20.437036950018083, 17.399044912417597, 49.072929423423496, 269.2553956858318, 80.72079256138973, 200.242742072974, 68.21238489882822, 208.28730597575378]) else: expected_profile = \ np.array([348.32049916992855, 143.49111631974688, 44.328145727486174, 8.759562612294948, 3.137819214539283, 14.846929648490525, 6.405154001052728, 20.437123731745928, 17.39892098642616, 49.07339619667625, 269.2533380585498, 80.72162511785703, 200.24505477294477, 68.21183884286609, 208.29025925025073]) assert_array_almost_equal(energy_profile, expected_profile, decimal=6)
def test_ssd_3d_demons(): r''' Register a stack of circles ('cylinder') before and after warping them with a synthetic diffeomorphism. This test is intended to detect regressions only: we saved the energy profile (the sequence of energy values at each iteration) of a working version of SSD in 3D using the Demons step, and this test checks that the current energy profile matches the saved one. The validation of the "working version" was done by registering the 18 manually annotated T1 brain MRI database IBSR with each other and computing the jaccard index for all 31 common anatomical regions. ''' moving, static = get_synthetic_warped_circle(30) moving[..., :8] = 0 moving[..., -1:-9:-1] = 0 static[..., :8] = 0 static[..., -1:-9:-1] = 0 #Create the SSD metric smooth = 4 step_type = 'demons' similarity_metric = metrics.SSDMetric(3, smooth=smooth, step_type=step_type) #Create the optimizer level_iters = [10, 5] step_length = 0.25 opt_tol = 1e-4 inv_iter = 20 inv_tol = 1e-3 ss_sigma_factor = 0.5 optimizer = imwarp.SymmetricDiffeomorphicRegistration( similarity_metric, level_iters, step_length, ss_sigma_factor, opt_tol, inv_iter, inv_tol) optimizer.verbosity = VerbosityLevels.DEBUG mapping = optimizer.optimize(static, moving, None) m = optimizer.get_map() assert_equal(mapping, m) energy_profile = subsample_profile(optimizer.full_energy_profile, 10) print(energy_profile) if USING_VC_SSE2: expected_profile = \ np.array([312.22706987, 154.65556884, 53.88543188, 9.11484007, 36.46592407, 13.20522299, 48.65663399, 14.91579802, 49.82954704, 14.92646254]) elif USING_GCC_SSE2: expected_profile = \ np.array([312.22706987, 154.65556885, 53.88455398, 9.11770682, 36.48642824, 13.21706748, 48.67710635, 14.91782047, 49.84142899, 14.92531294]) assert_array_almost_equal(energy_profile, expected_profile, decimal=4)
def test_optimizer_exceptions(): #An arbitrary valid metric metric = metrics.SSDMetric(2) # The metric must not be None assert_raises(ValueError, imwarp.SymmetricDiffeomorphicRegistration, None) # The iterations list must not be empty assert_raises(ValueError, imwarp.SymmetricDiffeomorphicRegistration, metric, []) optimizer = imwarp.SymmetricDiffeomorphicRegistration(metric, None) #Verify the default iterations list assert_array_equal(optimizer.level_iters, [100,100,25]) #Verify exception thrown when attepting to fit the energy profile without enough data assert_raises(ValueError, optimizer._get_energy_derivative)
def test_ssd_3d_demons(): r''' Register a stack of circles ('cylinder') before and after warping them with a synthetic diffeomorphism. This test is intended to detect regressions only: we saved the energy profile (the sequence of energy values at each iteration) of a working version of SSD in 3D using the Demons step, and this test checks that the current energy profile matches the saved one. The validation of the "working version" was done by registering the 18 manually annotated T1 brain MRI database IBSR with each other and computing the jaccard index for all 31 common anatomical regions. ''' moving, static = get_synthetic_warped_circle(30) moving[...,:8] = 0 moving[...,-1:-9:-1] = 0 static[...,:8] = 0 static[...,-1:-9:-1] = 0 #Create the SSD metric smooth = 4 step_type = 'demons' similarity_metric = metrics.SSDMetric(3, smooth=smooth, step_type=step_type) #Create the optimizer level_iters = [10, 5] step_length = 0.25 opt_tol = 1e-4 inv_iter = 20 inv_tol = 1e-3 ss_sigma_factor = 0.5 optimizer = imwarp.SymmetricDiffeomorphicRegistration(similarity_metric, level_iters, step_length, ss_sigma_factor, opt_tol, inv_iter, inv_tol) optimizer.verbosity = VerbosityLevels.DEBUG mapping = optimizer.optimize(static, moving, None) m = optimizer.get_map() assert_equal(mapping, m) energy_profile = np.array(optimizer.full_energy_profile) if floating is np.float32: expected_profile = \ np.array([312.22706987, 154.65556885, 53.88594419, 9.22626825, 36.50370933, 13.54829978, 49.57619437, 15.71122527, 53.45897119, 15.62018739, 521.95785712, 158.16217928, 182.49116432, 144.91081752, 176.6810387]) else: expected_profile = \ np.array([312.22709468, 154.65706498, 53.8856324, 8.90160898, 34.91911552, 12.66043296, 49.61341791, 15.14198327, 52.25467529, 18.88243845, 490.48088231, 149.29027701, 192.26219053, 137.5291187, 187.2795753]) assert_array_almost_equal(energy_profile, expected_profile, decimal=6)
def test_ssd_3d_gauss_newton(): r""" Test 3D SyN with SSD metric, Gauss-Newton optimizer Register a stack of circles ('cylinder') before and after warping them with a synthetic diffeomorphism. We verify that the final registration is of good quality. """ moving, static = get_synthetic_warped_circle(35) moving[..., :10] = 0 moving[..., -1:-11:-1] = 0 static[..., :10] = 0 static[..., -1:-11:-1] = 0 # Create the SSD metric smooth = 4 inner_iter = 5 step_type = 'gauss_newton' similarity_metric = metrics.SSDMetric(3, smooth, inner_iter, step_type) # Create the optimizer level_iters = [10, 10] step_length = 0.1 opt_tol = 1e-4 inv_iter = 20 inv_tol = 1e-3 ss_sigma_factor = 0.5 optimizer = imwarp.SymmetricDiffeomorphicRegistration( similarity_metric, level_iters, step_length, ss_sigma_factor, opt_tol, inv_iter, inv_tol) optimizer.verbosity = VerbosityLevels.DEBUG mapping = optimizer.optimize(static, moving, None) m = optimizer.get_map() assert_equal(mapping, m) warped = mapping.transform(moving) starting_energy = np.sum((static - moving)**2) final_energy = np.sum((static - warped)**2) reduced = 1.0 - final_energy / starting_energy assert(reduced > 0.9)
def test_ssd_2d_gauss_newton(): r''' Classical Circle-To-C experiment for 2D Monomodal registration. This test is intended to detect regressions only: we saved the energy profile (the sequence of energy values at each iteration) of a working version of SSD in 2D using the Gauss Newton step, and this test checks that the current energy profile matches the saved one. ''' fname_moving = get_data('reg_o') fname_static = get_data('reg_c') moving = np.load(fname_moving) static = np.load(fname_static) moving = np.array(moving, dtype=floating) static = np.array(static, dtype=floating) moving = (moving-moving.min())/(moving.max() - moving.min()) static = (static-static.min())/(static.max() - static.min()) #Create the SSD metric smooth = 4 inner_iter = 5 step_type = 'gauss_newton' similarity_metric = metrics.SSDMetric(2, smooth, inner_iter, step_type) #Configure and run the Optimizer level_iters = [200, 100, 50, 25] step_length = 0.5 opt_tol = 1e-4 inv_iter = 40 inv_tol = 1e-3 ss_sigma_factor = 0.2 optimizer = imwarp.SymmetricDiffeomorphicRegistration(similarity_metric, level_iters, step_length, ss_sigma_factor, opt_tol, inv_iter, inv_tol) #test callback not being called optimizer.INIT_START_CALLED = 0 optimizer.INIT_END_CALLED = 0 optimizer.OPT_START_CALLED = 0 optimizer.OPT_END_CALLED = 0 optimizer.SCALE_START_CALLED = 0 optimizer.SCALE_END_CALLED = 0 optimizer.ITER_START_CALLED = 0 optimizer.ITER_END_CALLED = 0 optimizer.verbosity = VerbosityLevels.DEBUG id = np.eye(3) mapping = optimizer.optimize(static, moving, id, id, id) m = optimizer.get_map() assert_equal(mapping, m) subsampled_energy_profile = subsample_profile( optimizer.full_energy_profile, 10) print(subsampled_energy_profile) if USING_VC_SSE2: expected_profile = \ np.array([312.68133316, 70.17782995, 21.38508088, 96.41054776, 49.990781, 43.11867579, 24.53952718, 51.0786643, 143.24848252, 150.48349573]) elif USING_GCC_SSE2: expected_profile = \ np.array([312.68133316, 70.17782938, 21.26798507, 96.51765054, 51.1495088, 37.86204803, 21.62425293, 49.44868302, 121.6643917, 137.91427228]) assert_array_almost_equal(subsampled_energy_profile, expected_profile, decimal = 5) assert_equal(optimizer.OPT_START_CALLED, 0) assert_equal(optimizer.OPT_END_CALLED, 0) assert_equal(optimizer.SCALE_START_CALLED, 0) assert_equal(optimizer.SCALE_END_CALLED, 0) assert_equal(optimizer.ITER_START_CALLED, 0) assert_equal(optimizer.ITER_END_CALLED, 0)
def test_ssd_2d_demons(): r''' Classical Circle-To-C experiment for 2D Monomodal registration. This test is intended to detect regressions only: we saved the energy profile (the sequence of energy values at each iteration) of a working version of SSD in 2D using the Demons step, and this test checks that the current energy profile matches the saved one. ''' fname_moving = get_data('reg_o') fname_static = get_data('reg_c') moving = np.load(fname_moving) static = np.load(fname_static) moving = np.array(moving, dtype=floating) static = np.array(static, dtype=floating) moving = (moving-moving.min())/(moving.max() - moving.min()) static = (static-static.min())/(static.max() - static.min()) #Create the SSD metric smooth = 4 step_type = 'demons' similarity_metric = metrics.SSDMetric(2, smooth=smooth, step_type=step_type) #Configure and run the Optimizer level_iters = [200, 100, 50, 25] step_length = 0.25 opt_tol = 1e-4 inv_iter = 40 inv_tol = 1e-3 ss_sigma_factor = 0.2 optimizer = imwarp.SymmetricDiffeomorphicRegistration(similarity_metric, level_iters, step_length, ss_sigma_factor, opt_tol, inv_iter, inv_tol) #test callback being called optimizer.INIT_START_CALLED = 0 optimizer.INIT_END_CALLED = 0 optimizer.OPT_START_CALLED = 0 optimizer.OPT_END_CALLED = 0 optimizer.SCALE_START_CALLED = 0 optimizer.SCALE_END_CALLED = 0 optimizer.ITER_START_CALLED = 0 optimizer.ITER_END_CALLED = 0 optimizer.callback_counter_test = 0 optimizer.callback = simple_callback optimizer.verbosity = VerbosityLevels.DEBUG mapping = optimizer.optimize(static, moving, None) m = optimizer.get_map() assert_equal(mapping, m) subsampled_energy_profile = subsample_profile( optimizer.full_energy_profile, 10) print(subsampled_energy_profile) if USING_VC_SSE2: expected_profile = \ np.array([312.6813333, 80.74625551, 49.43591374, 34.08871301, 25.18286981, 17.78955273, 25.91334939, 20.16932281, 43.86083145, 79.0966558 ]) elif USING_GCC_SSE2: expected_profile = \ np.array([312.6813333, 98.17321941, 60.98300837, 47.75387157, 34.11067498, 122.91901409, 19.75599298, 14.28763847, 36.33599718, 88.62426913]) assert_array_almost_equal(subsampled_energy_profile, expected_profile, decimal=5) assert_equal(optimizer.OPT_START_CALLED, 1) assert_equal(optimizer.OPT_END_CALLED, 1) assert_equal(optimizer.SCALE_START_CALLED, 1) assert_equal(optimizer.SCALE_END_CALLED, 1) assert_equal(optimizer.ITER_START_CALLED, 1) assert_equal(optimizer.ITER_END_CALLED, 1)
def test_ssd_2d_gauss_newton(): r''' Classical Circle-To-C experiment for 2D Monomodal registration. This test is intended to detect regressions only: we saved the energy profile (the sequence of energy values at each iteration) of a working version of SSD in 2D using the Gauss Newton step, and this test checks that the current energy profile matches the saved one. ''' fname_moving = get_data('reg_o') fname_static = get_data('reg_c') moving = np.load(fname_moving) static = np.load(fname_static) moving = np.array(moving, dtype=floating) static = np.array(static, dtype=floating) moving = (moving-moving.min())/(moving.max() - moving.min()) static = (static-static.min())/(static.max() - static.min()) #Create the SSD metric smooth = 4 inner_iter = 5 step_type = 'gauss_newton' similarity_metric = metrics.SSDMetric(2, smooth, inner_iter, step_type) #Configure and run the Optimizer level_iters = [200, 100, 50, 25] step_length = 0.5 opt_tol = 1e-4 inv_iter = 40 inv_tol = 1e-3 ss_sigma_factor = 0.2 optimizer = imwarp.SymmetricDiffeomorphicRegistration(similarity_metric, level_iters, step_length, ss_sigma_factor, opt_tol, inv_iter, inv_tol) #test callback not being called optimizer.INIT_START_CALLED = 0 optimizer.INIT_END_CALLED = 0 optimizer.OPT_START_CALLED = 0 optimizer.OPT_END_CALLED = 0 optimizer.SCALE_START_CALLED = 0 optimizer.SCALE_END_CALLED = 0 optimizer.ITER_START_CALLED = 0 optimizer.ITER_END_CALLED = 0 optimizer.verbosity = VerbosityLevels.DEBUG mapping = optimizer.optimize(static, moving, np.eye(3), np.eye(3), np.eye(3)) m = optimizer.get_map() assert_equal(mapping, m) subsampled_energy_profile = np.array(optimizer.full_energy_profile[::10]) if floating is np.float32: expected_profile = \ np.array([312.68133316, 79.40404517, 23.3715698, 125.02700267, 59.79982213, 34.64971733, 23.37131446, 171.28250576, 62.22266377, 125.24392168]) else: expected_profile = \ np.array([312.68133361, 79.40404354, 23.34588446, 124.3247997, 61.69601973, 38.15047181, 23.53315113, 80.0791295, 57.21700113, 143.73270476]) assert_array_almost_equal(subsampled_energy_profile, expected_profile) assert_equal(optimizer.OPT_START_CALLED, 0) assert_equal(optimizer.OPT_END_CALLED, 0) assert_equal(optimizer.SCALE_START_CALLED, 0) assert_equal(optimizer.SCALE_END_CALLED, 0) assert_equal(optimizer.ITER_START_CALLED, 0) assert_equal(optimizer.ITER_END_CALLED, 0)
def test_ssd_2d_demons(): r''' Classical Circle-To-C experiment for 2D Monomodal registration. This test is intended to detect regressions only: we saved the energy profile (the sequence of energy values at each iteration) of a working version of SSD in 2D using the Demons step, and this test checks that the current energy profile matches the saved one. ''' fname_moving = get_data('reg_o') fname_static = get_data('reg_c') moving = np.load(fname_moving) static = np.load(fname_static) moving = np.array(moving, dtype=floating) static = np.array(static, dtype=floating) moving = (moving-moving.min())/(moving.max() - moving.min()) static = (static-static.min())/(static.max() - static.min()) #Create the SSD metric smooth = 4 step_type = 'demons' similarity_metric = metrics.SSDMetric(2, smooth=smooth, step_type=step_type) #Configure and run the Optimizer level_iters = [200, 100, 50, 25] step_length = 0.25 opt_tol = 1e-4 inv_iter = 40 inv_tol = 1e-3 ss_sigma_factor = 0.2 optimizer = imwarp.SymmetricDiffeomorphicRegistration(similarity_metric, level_iters, step_length, ss_sigma_factor, opt_tol, inv_iter, inv_tol) #test callback being called optimizer.INIT_START_CALLED = 0 optimizer.INIT_END_CALLED = 0 optimizer.OPT_START_CALLED = 0 optimizer.OPT_END_CALLED = 0 optimizer.SCALE_START_CALLED = 0 optimizer.SCALE_END_CALLED = 0 optimizer.ITER_START_CALLED = 0 optimizer.ITER_END_CALLED = 0 optimizer.callback_counter_test = 0 optimizer.callback = simple_callback optimizer.verbosity = VerbosityLevels.DEBUG mapping = optimizer.optimize(static, moving, None) m = optimizer.get_map() assert_equal(mapping, m) subsampled_energy_profile = np.array(optimizer.full_energy_profile[::10]) if floating is np.float32: expected_profile = \ np.array([312.6813333, 162.57756447, 99.2766679, 77.38698935, 61.75415204, 55.37420428, 46.36872571, 41.81811505, 36.38683617, 33.03952963, 30.91409901, 54.41447237, 23.40232241, 12.75092466, 10.19231733, 9.21058037, 57.4636143, 38.94004856, 36.26093212, 108.0136453, 81.35521049, 74.61956833]) else: expected_profile = \ np.array([312.68133361, 162.57744066, 99.27669798, 77.38683186, 61.75391429, 55.3740711, 46.36870776, 41.81809239, 36.3898153, 32.78365961, 30.69843811, 53.67073767, 21.74630524, 11.98102583, 11.51086685, 55.30707781, 39.88467545, 34.29444978, 33.10822964, 122.64743831, 84.18144073, 75.60088687]) assert_array_almost_equal(subsampled_energy_profile, expected_profile) assert_equal(optimizer.OPT_START_CALLED, 1) assert_equal(optimizer.OPT_END_CALLED, 1) assert_equal(optimizer.SCALE_START_CALLED, 1) assert_equal(optimizer.SCALE_END_CALLED, 1) assert_equal(optimizer.ITER_START_CALLED, 1) assert_equal(optimizer.ITER_END_CALLED, 1)