def test_homogenous_coordinates_violation_warning(self): affine = np.ones((4, 4)) array = np.arange(4 * 5 * 6 * 3).reshape(4, 5, 6, 3) expected_warning = RuntimeWarning match = "affine is not in homogenous coordinates.\naffine\[-1] should be zeros with a 1 on the right." with pytest.warns(expected_warning, match=match): _multiply_coords_by_affine(affine, array)
def test_non_square_affine(self): affine = np.eye(4)[:3] array = np.arange(4 * 5 * 6 * 3).reshape(4, 5, 6, 3) expected_exception = ValueError match = "affine must be a square matrix." with pytest.raises(expected_exception, match=match): _multiply_coords_by_affine(affine, array)
def test_incompatible_affine_and_array(self): affine = np.eye(4) array = np.arange(4 * 5 * 6 * 2).reshape(4, 5, 6, 2) expected_exception = ValueError match = "array is incompatible with affine. The length of the last dimension of array should be 1 less than the length of affine." with pytest.raises(expected_exception, match=match): _multiply_coords_by_affine(affine, array)
def test_3D_affine_array(self): affine = np.eye(4)[None] array = np.arange(4 * 5 * 6 * 3).reshape(4, 5, 6, 3) expected_exception = ValueError match = "affine must be a 2-dimensional matrix." with pytest.raises(expected_exception, match=match): _multiply_coords_by_affine(affine, array)
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_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)