def test_identity_affine_constant_velocity_fields(self, deform_to): num_timesteps = 10 template_shape = (3, 4, 5) template_resolution = 1 target_shape = (2, 4, 6) target_resolution = 1 velocity_fields = np.ones( (*template_shape, num_timesteps, len(template_shape))) velocity_field_resolution = 1 affine = np.eye(4) if deform_to == "template": expected_output = (_lddmm_utilities._compute_coords( template_shape, template_resolution) + 1) elif deform_to == "target": expected_output = (_lddmm_utilities._compute_coords( target_shape, target_resolution) - 1) position_field = generate_position_field( affine=affine, velocity_fields=velocity_fields, velocity_field_resolution=velocity_field_resolution, template_shape=template_shape, template_resolution=template_resolution, target_shape=target_shape, target_resolution=target_resolution, deform_to=deform_to, ) assert np.allclose(position_field, expected_output)
def test_identity_position_field_different_output_resolution(self): subject = np.array([ [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], ]) subject_resolution = 1 output_resolution = 2 output_shape = None position_field_resolution = subject_resolution position_field = _lddmm_utilities._compute_coords( subject.shape, position_field_resolution) deformed_subject = _transform_image( subject=subject, subject_resolution=subject_resolution, output_resolution=output_resolution, output_shape=output_shape, position_field=position_field, position_field_resolution=position_field_resolution, ) expected_output = np.array([ [0, 0, 0, 0], [0, 1, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0], ]) assert np.allclose(deformed_subject, expected_output)
def test_identity_position_fields(self, deform_to): subject = np.array([ [0, 0, 0, 0], [0, 1, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0], ]) subject_resolution = 1 output_resolution = None output_shape = None template_shape = (3, 4) template_resolution = 1 target_shape = (2, 5) target_resolution = 1 extrapolation_fill_value = np.quantile(subject, 10**-subject.ndim) affine_phi = _lddmm_utilities._compute_coords(template_shape, template_resolution) phi_inv_affine_inv = _lddmm_utilities._compute_coords( target_shape, target_resolution) expected_output = _transform_image( subject, subject_resolution, output_resolution, output_shape, position_field=affine_phi if deform_to == "template" else phi_inv_affine_inv, position_field_resolution=template_resolution if deform_to == "template" else target_resolution, extrapolation_fill_value=extrapolation_fill_value, ) deformed_subject = lddmm_transform_image( subject=subject, subject_resolution=subject_resolution, output_resolution=output_resolution, deform_to=deform_to, extrapolation_fill_value=extrapolation_fill_value, affine_phi=affine_phi, phi_inv_affine_inv=phi_inv_affine_inv, template_resolution=template_resolution, target_resolution=target_resolution, ) assert np.array_equal(deformed_subject, expected_output)
def test_2D_shape_zero_origin(self): kwargs = dict(shape=(3, 4), resolution=1, origin="zero") correct_output = np.array([ [[0, 0], [0, 1], [0, 2], [0, 3]], [[1, 0], [1, 1], [1, 2], [1, 3]], [[2, 0], [2, 1], [2, 2], [2, 3]], ]) assert np.array_equal(_compute_coords(**kwargs), correct_output)
def test_identity_position_field(self): subject = np.arange(3 * 4).reshape(3, 4) subject_resolution = 1 position_field_resolution = subject_resolution position_field = _lddmm_utilities._compute_coords( subject.shape, position_field_resolution) points = _lddmm_utilities._compute_coords(subject.shape, position_field_resolution) transformed_points = _transform_points( points=points, position_field=position_field, position_field_resolution=position_field_resolution, ) expected_output = points assert np.array_equal(transformed_points, expected_output)
def test_rotational_affine_identity_velocity_fields(self, deform_to): num_timesteps = 10 template_shape = (3, 4, 5) template_resolution = 1 target_shape = (2, 4, 6) target_resolution = 1 velocity_fields = np.zeros( (*template_shape, num_timesteps, len(template_shape))) velocity_field_resolution = 1 # Indicates a 90 degree rotation to the right. affine = np.array([ [0, 1, 0, 0], [-1, 0, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1], ]) if deform_to == "template": expected_output = _lddmm_utilities._multiply_coords_by_affine( affine, _lddmm_utilities._compute_coords(template_shape, template_resolution), ) elif deform_to == "target": expected_output = _lddmm_utilities._multiply_coords_by_affine( inv(affine), _lddmm_utilities._compute_coords(target_shape, target_resolution), ) position_field = generate_position_field( affine=affine, velocity_fields=velocity_fields, velocity_field_resolution=velocity_field_resolution, template_shape=template_shape, template_resolution=template_resolution, target_shape=target_shape, target_resolution=target_resolution, deform_to=deform_to, ) assert np.allclose(position_field, expected_output)
def test_identity_affine_3D(self): affine = ( np.eye(4) + np.append(np.arange(3 * 4).reshape(3, 4), np.zeros((1, 4)), 0) ** 2 ) array = _compute_coords((3, 4, 5), 1) result = _multiply_coords_by_affine(affine, array) arrays = [] for dim in range(3): arrays.append(np.sum(affine[dim, :-1] * array, axis=-1) + affine[dim, -1]) expected = np.stack(arrays=arrays, axis=-1) assert np.array_equal(result, expected)
def test_identity_position_fields(self, deform_to): template_shape = (3, 4) template_resolution = 1 target_shape = (2, 5) target_resolution = 1 affine_phi = _lddmm_utilities._compute_coords(template_shape, template_resolution) phi_inv_affine_inv = _lddmm_utilities._compute_coords( target_shape, target_resolution) if deform_to == "template": points = _lddmm_utilities._compute_coords(target_shape, target_resolution) position_field = phi_inv_affine_inv position_field_resolution = target_resolution else: points = _lddmm_utilities._compute_coords(template_shape, template_resolution) position_field = affine_phi position_field_resolution = template_resolution expected_output = _transform_points( points=points, position_field=position_field, position_field_resolution=position_field_resolution, ) transformed_points = lddmm_transform_points( points=points, deform_to=deform_to, affine_phi=affine_phi, phi_inv_affine_inv=phi_inv_affine_inv, template_resolution=template_resolution, target_resolution=target_resolution, ) assert np.array_equal(transformed_points, expected_output)
def test_constant_position_field_trivial_extrapolation(self): # Note: applying a leftward shift to the position_field is done by subtracting 1 from the appropriate dimension. # The corresponding effect on the deformed_subject is a shift to the right. subject = np.array([ [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], ]) subject_resolution = 1 output_resolution = 1 output_shape = None position_field_resolution = subject_resolution position_field = _lddmm_utilities._compute_coords( subject.shape, position_field_resolution) + [ 0, -1, ] # Shift to the left by 1. deformed_subject = _transform_image( subject=subject, subject_resolution=subject_resolution, output_resolution=output_resolution, output_shape=output_shape, position_field=position_field, position_field_resolution=position_field_resolution, ) expected_output = np.array([ [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 1, 1, 1, 0], [0, 0, 0, 1, 1, 1, 1, 0], [0, 0, 0, 1, 1, 1, 1, 0], [0, 0, 0, 1, 1, 1, 1, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], ]) assert np.allclose(deformed_subject, expected_output)
def test_rotational_position_field(self): # Note: applying an affine indicating a clockwise-rotation to a position_field produces a position _ield rotated counter-clockwise. # The corresponding effect on the deformed_subject is a counter-clockwise rotation. subject = np.array([ [0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 1, 1], ]) subject_resolution = 1 output_resolution = 1 output_shape = None position_field_resolution = subject_resolution # Indicates a 90 degree rotation to the right. affine = np.array([ [0, 1, 0], [-1, 0, 0], [0, 0, 1], ]) position_field = _lddmm_utilities._multiply_coords_by_affine( affine, _lddmm_utilities._compute_coords(subject.shape, position_field_resolution), ) deformed_subject = _transform_image( subject=subject, subject_resolution=subject_resolution, output_resolution=output_resolution, output_shape=output_shape, position_field=position_field, position_field_resolution=position_field_resolution, ) expected_output = np.array([ [0, 0, 0, 1], [0, 0, 0, 1], [1, 1, 1, 1], [0, 0, 0, 0], ]) assert np.allclose(deformed_subject, expected_output)
def test_rotational_position_field(self): # Note: applying an affine indicating a clockwise-rotation to a position_field produces a position _ield rotated counter-clockwise. # The corresponding effect on a deformed image is a counter-clockwise rotation. subject = np.array([ [0, 1, 0], [0, 1, 0], [0, 1, 1], ]) subject_resolution = 1 position_field_resolution = subject_resolution # Indicates a 90 degree rotation to the right. affine = np.array([ [0, 1, 0], [-1, 0, 0], [0, 0, 1], ]) position_field = _lddmm_utilities._multiply_coords_by_affine( affine, _lddmm_utilities._compute_coords(subject.shape, position_field_resolution), ) # The middle column. points = np.array([ [-1, 0], [0, 0], [1, 0], ]) transformed_points = _transform_points( points=points, position_field=position_field, position_field_resolution=position_field_resolution, ) # The middle row. expected_output = np.array([ [0, 1], [0, 0], [0, -1], ]) assert np.array_equal(transformed_points, expected_output)
def test_identity_position_field_equal_output_resolution(self): subject = np.arange(3 * 4).reshape(3, 4) subject_resolution = 1 output_resolution = 1 output_shape = None position_field_resolution = subject_resolution position_field = _lddmm_utilities._compute_coords( subject.shape, position_field_resolution) deformed_subject = _transform_image( subject=subject, subject_resolution=subject_resolution, output_resolution=output_resolution, output_shape=output_shape, position_field=position_field, position_field_resolution=position_field_resolution, ) expected_output = subject assert np.allclose(deformed_subject, expected_output)
def test_constant_position_field(self): # Note: applying a leftward shift to the position_field is done by subtracting 1 from the appropriate dimension. # The corresponding effect on a deformed image is a shift to the right. subject = np.array([ [0, 1, 3], [4, 5, 6], [7, 8, 9], ]) subject_resolution = 1 position_field_resolution = subject_resolution position_field = _lddmm_utilities._compute_coords( subject.shape, position_field_resolution) + [ 0, -1, ] # Shift to the left by 1. # The right column. points = np.array([ [-1, 1], [0, 1], [1, 1], ]) transformed_points = _transform_points( points=points, position_field=position_field, position_field_resolution=position_field_resolution, ) # The middle column. expected_output = np.array([ [-1, 0], [0, 0], [1, 0], ]) assert np.array_equal(transformed_points, expected_output)
def test_constant_position_field_linear_extrapolation(self): # Idiosyncratic extrapolation behavior is demonstrated with a nonzero gradient at the extrapolated edge. subject = np.array([ [0, 0, 0, 0], [0, 1, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0], ]) subject_resolution = 1 output_resolution = 1 output_shape = None position_field_resolution = subject_resolution position_field = _lddmm_utilities._compute_coords( subject.shape, position_field_resolution) + [ 0, -1, ] # Shift to the left by 1. deformed_subject = _transform_image( subject=subject, subject_resolution=subject_resolution, output_resolution=output_resolution, output_shape=output_shape, position_field=position_field, position_field_resolution=position_field_resolution, ) expected_output = np.array([ [0, 0, 0, 0], [-1, 0, 1, 1], [-1, 0, 1, 1], [0, 0, 0, 0], ]) assert np.allclose(deformed_subject, expected_output)
def test_1D_shape_center_origin(self): kwargs = dict(shape=5, resolution=1, origin="center") correct_output = np.array([[-2], [-1], [0], [1], [2]]) assert np.array_equal(_compute_coords(**kwargs), correct_output)