def test_construct_rt(): eye = Rototrans() np.testing.assert_equal(eye.time.size, 1) np.testing.assert_equal(eye.sel(time=0), np.eye(4)) eye = Rototrans.from_euler_angles() np.testing.assert_equal(eye.time.size, 1) np.testing.assert_equal(eye.sel(time=0), np.eye(4)) # Test the way to create a rt, but not when providing bot angles and sequence nb_frames = 10 random_vector = Angles(np.random.rand(3, 1, nb_frames)) # with angles rt_random_angles = Rototrans.from_euler_angles(angles=random_vector, angle_sequence="xyz") np.testing.assert_equal(rt_random_angles.time.size, nb_frames) np.testing.assert_equal(rt_random_angles[:-1, -1:, :], np.zeros((3, 1, nb_frames))) # Translation is 0 # with translation rt_random_translation = Rototrans.from_euler_angles( translations=random_vector) np.testing.assert_equal(rt_random_translation.time.size, nb_frames) np.testing.assert_equal( rt_random_translation[:3, :3, :], np.repeat(np.eye(3)[:, :, np.newaxis], nb_frames, axis=2), ) # rotation is eye3 np.arange(0, rt_random_angles.time.size / 0.5, 1 / 0.5) rt_with_time = Rototrans( rt_random_angles, time=np.arange(0, rt_random_angles.time.size / 100, 1 / 100), ) assert rt_with_time.time[-1] == 0.09 with pytest.raises(IndexError): Rototrans(data=np.zeros(1)) with pytest.raises(ValueError): Rototrans(data=np.zeros((4, 4, 1))) with pytest.raises(ValueError): Rototrans(data=np.ones((4, 4, 1))) with pytest.raises(IndexError): Rototrans.from_euler_angles( angles=random_vector[..., :5], translations=random_vector, angle_sequence="x", ) with pytest.raises(IndexError): Rototrans.from_euler_angles(angles=random_vector, angle_sequence="x") with pytest.raises(ValueError): Rototrans.from_euler_angles(angles=random_vector, angle_sequence="nop")
def test_euler2rot_rot2euleur(seq, angles=ANGLES, epsilon=EPSILON): if seq == "zyzz": angles_to_test = angles[:3, ...] else: angles_to_test = angles[:len(seq), ...] r = Rototrans.from_euler_angles(angles=angles_to_test, angle_sequence=seq) a = Angles.from_rototrans(rt=r, angle_sequence=seq) np.testing.assert_array_less((a - angles_to_test).meca.abs().sum(), epsilon)
def test_average_rt(): # TODO: investigate why this does not work # angles = Angles.from_random_data(size=(3, 1, 100)) # or # angles = Angles(np.arange(300).reshape((3, 1, 100))) angles = Angles(np.random.rand(3, 1, 100)) seq = "xyz" rt = Rototrans.from_euler_angles(angles, seq) rt_mean = Rototrans.from_averaged_rototrans(rt) angles_mean = Angles.from_rototrans(rt_mean, seq).isel(time=0) angles_mean_ref = Angles.from_rototrans(rt, seq).mean(dim="time") np.testing.assert_array_almost_equal(angles_mean, angles_mean_ref, decimal=2)
def test_rotate(): n_frames = 100 n_markers = 10 angles = Angles.from_random_data(size=(3, 1, n_frames)) rt = Rototrans.from_euler_angles(angles, "xyz") markers = Markers.from_random_data(size=(3, n_markers, n_frames)) rotated_markers = Markers.from_rototrans(markers, rt) expected_rotated_marker = np.ndarray((4, n_markers, n_frames)) for marker in range(n_markers): for frame in range(n_frames): expected_rotated_marker[:, marker, frame] = np.dot( rt.isel(time=frame), markers.isel(channel=marker, time=frame), ) np.testing.assert_array_almost_equal(rotated_markers, expected_rotated_marker, decimal=10) rotated_markers = Markers.from_rototrans(markers.isel(time=0), rt.isel(time=0)) expected_rotated_marker = np.ndarray(rotated_markers.shape) for marker in range(n_markers): expected_rotated_marker[:, marker] = np.dot( rt.isel(time=0), markers.isel(channel=marker, time=0)) np.testing.assert_array_almost_equal(rotated_markers, expected_rotated_marker, decimal=10) rotated_markers = Markers.from_rototrans(markers, rt.isel(time=0)) expected_rotated_marker = np.ndarray(rotated_markers.shape) for marker in range(n_markers): expected_rotated_marker[:, marker] = np.dot(rt.isel(time=0), markers.isel(channel=marker)) np.testing.assert_array_almost_equal(rotated_markers, expected_rotated_marker, decimal=10) with pytest.raises(ValueError): Markers.from_rototrans(markers.isel(time=0), rt)
def test_average_rt(): seq = "xyz" angles_size = (3, 1, 100) ref_angles_from_rt_mean = [0.25265133, 0.57436872, 0.79133042] restart_seed() angles = Angles.from_random_data(size=angles_size) # min-max normalization to keep the angles low angles = angles.pipe(lambda x: (x - x.min()) / (x.max() - x.min())) rt = Rototrans.from_euler_angles(angles, seq) rt_mean = Rototrans.from_averaged_rototrans(rt) angles_from_rt_mean = Angles.from_rototrans(rt_mean, seq) np.testing.assert_almost_equal(angles_from_rt_mean.data.ravel(), ref_angles_from_rt_mean, decimal=4)
def test_rt_transpose(): n_frames = 10 angles = Angles.from_random_data(size=(3, 1, n_frames)) rt = Rototrans.from_euler_angles(angles, angle_sequence="xyz") rt_t = Rototrans.from_transposed_rototrans(rt) rt_t_expected = np.zeros((4, 4, n_frames)) rt_t_expected[3, 3, :] = 1 for row in range(rt.row.size): for col in range(rt.col.size): for frame in range(rt.time.size): rt_t_expected[col, row, frame] = rt[row, col, frame] for frame in range(rt.time.size): rt_t_expected[:3, 3, frame] = -rt_t_expected[:3, :3, frame].dot( rt[:3, 3, frame]) np.testing.assert_array_almost_equal(rt_t, rt_t_expected, decimal=10)
vtkModelMid = VtkModel(vtkWindow, markers_color=(0, 0, 1), markers_size=10.0, markers_opacity=0.5, rt_length=100) vtkModelFromC3d = VtkModel(vtkWindow, markers_color=(0, 1, 0), markers_size=10.0, markers_opacity=0.5, rt_length=100) # Create some RotoTrans attached to the first model all_rt_real = [] all_rt_real.append( Rototrans.from_euler_angles(angles=Angles(np.zeros((3, 1, 1))), angle_sequence="yxz", translations=d[:, [0], [0]])) all_rt_real.append( Rototrans.from_euler_angles(angles=Angles(np.zeros((3, 1, 1))), angle_sequence="yxz", translations=d[:, [0], [0]])) # Create some Rototrans attached to the second model one_rt = Rototrans.from_markers( origin=d[:, [3, 5], :].mean("channel", keepdims=True), axis_1=d[:, [4, 3], :], axis_2=d[:, [4, 5], :], axes_name="zx", axis_to_recalculate="z", )