def test_rt_transpose(): rt = Rototrans.from_random_data() rt_t = Rototrans.from_transposed_rototrans(rt) rt_t_expected = np.zeros((4, 4, rt.time.size)) 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)
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_rototrans_creation(): dims = ("row", "col", "time") array = Rototrans() np.testing.assert_array_equal(x=array, y=xr.DataArray(np.eye(4)[..., np.newaxis])) assert array.dims == dims array = Rototrans(MARKERS_DATA.values, time=MARKERS_DATA.time) is_expected_array(array, **EXPECTED_VALUES[67]) size = 4, 4, 100 array = Rototrans.from_random_data(size=size) assert array.shape == size assert array.dims == dims with pytest.raises(ValueError): Angles(ANALOGS_DATA)
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)
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_rototrans_creation(): dims = ("row", "col", "time") array = Rototrans() np.testing.assert_array_equal(x=array, y=xr.DataArray(np.eye(4)[..., np.newaxis])) assert array.dims == dims data = Markers(MARKERS_DATA.values) array = Rototrans.from_markers( origin=data.isel(channel=[0]), axis_1=data.isel(channel=[0, 1]), axis_2=data.isel(channel=[0, 2]), axes_name="xy", axis_to_recalculate="y", ) is_expected_array(array, **EXPECTED_VALUES[67]) size = 4, 4, 100 array = Rototrans.from_random_data(size=size) assert array.shape == size assert array.dims == dims with pytest.raises(ValueError): Angles(ANALOGS_DATA)
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)
w = vertcat(transX, transY, transZ, angleX, angleY, angleZ) prob = {'f': J, 'x': w} options = { 'ipopt.hessian_approximation': "exact", # 'ipopt.tol':1e-10,'ipopt.dual_inf_tol':1e-15 } solver = nlpsol('solver', 'ipopt', prob, options) w0 = np.zeros((6, 1)) # w0[0]= marker_model[0,0,0] - marker_treat[0,0,0] # w0[1]= marker_model[1,0,0] - marker_treat[1,0,0] # w0[2]= marker_model[2,0,0] - marker_treat[2,0,0] solve = solver(x0=w0, lbx=-1000, ubx=10000) w_opt = solve['x'] print(w_opt) rt = Rototrans((RT(w_opt[0], w_opt[1], w_opt[2], w_opt[3], w_opt[4], w_opt[5]))) # rt = Rototrans((RT(0.841114, 0.103637, -0.596597, -0.458244, 0.145129, 3.21253))) marker_rotate = Markers.from_rototrans(marker_treat, rt) # Data for three-dimensional scattered points ax = plt.axes(projection='3d') zdata = marker_rotate[2, :, 0] xdata = marker_rotate[0, :, 0] ydata = marker_rotate[1, :, 0] ax.scatter3D(xdata, ydata, zdata, cmap='Greens') zdata = marker_model[2, :, 0] xdata = marker_model[0, :, 0] ydata = marker_model[1, :, 0] ax.scatter3D(xdata, ydata, zdata, edgecolors="red") ax.view_init(60, 35) plt.show()
def test_rt_from_markers(): all_m = Markers.from_random_data() rt_xy = Rototrans.from_markers( origin=all_m.isel(channel=[0]), axis_1=all_m.isel(channel=[0, 1]), axis_2=all_m.isel(channel=[0, 2]), axes_name="xy", axis_to_recalculate="y", ) rt_yx = Rototrans.from_markers( origin=all_m.isel(channel=[0]), axis_1=all_m.isel(channel=[0, 2]), axis_2=all_m.isel(channel=[0, 1]), axes_name="yx", axis_to_recalculate="y", ) rt_xy_x_recalc = Rototrans.from_markers( origin=all_m.isel(channel=[0]), axis_1=all_m.isel(channel=[0, 1]), axis_2=all_m.isel(channel=[0, 2]), axes_name="yx", axis_to_recalculate="x", ) rt_xy_x_recalc = rt_xy_x_recalc.isel(col=[1, 0, 2, 3]) rt_xy_x_recalc[:, 2, :] = -rt_xy_x_recalc[:, 2, :] rt_yz = Rototrans.from_markers( origin=all_m.isel(channel=[0]), axis_1=all_m.isel(channel=[0, 1]), axis_2=all_m.isel(channel=[0, 2]), axes_name="yz", axis_to_recalculate="z", ) rt_zy = Rototrans.from_markers( origin=all_m.isel(channel=[0]), axis_1=all_m.isel(channel=[0, 2]), axis_2=all_m.isel(channel=[0, 1]), axes_name="zy", axis_to_recalculate="z", ) rt_xy_from_yz = rt_yz.isel(col=[1, 2, 0, 3]) rt_xz = Rototrans.from_markers( origin=all_m.isel(channel=[0]), axis_1=all_m.isel(channel=[0, 1]), axis_2=all_m.isel(channel=[0, 2]), axes_name="xz", axis_to_recalculate="z", ) rt_zx = Rototrans.from_markers( origin=all_m.isel(channel=[0]), axis_1=all_m.isel(channel=[0, 2]), axis_2=all_m.isel(channel=[0, 1]), axes_name="zx", axis_to_recalculate="z", ) rt_xy_from_zx = rt_xz.isel(col=[0, 2, 1, 3]) rt_xy_from_zx[:, 2, :] = -rt_xy_from_zx[:, 2, :] np.testing.assert_array_equal(rt_xy, rt_xy_x_recalc) np.testing.assert_array_equal(rt_xy, rt_yx) np.testing.assert_array_equal(rt_yz, rt_zy) np.testing.assert_array_equal(rt_xz, rt_zx) np.testing.assert_array_equal(rt_xy, rt_xy_from_yz) np.testing.assert_array_equal(rt_xy, rt_xy_from_zx) # Produce one that we know the solution ref_m = Markers( np.array(((1, 2, 3), (4, 5, 6), (6, 5, 4))).T[:, :, np.newaxis]) rt_xy_from_known_m = Rototrans.from_markers( origin=ref_m.isel(channel=[0]), axis_1=ref_m.isel(channel=[0, 1]), axis_2=ref_m.isel(channel=[0, 2]), axes_name="xy", axis_to_recalculate="y", ) rt_xy_expected = Rototrans( np.array([ [0.5773502691896257, 0.7071067811865475, -0.408248290463863, 1.0], [0.5773502691896257, 0.0, 0.816496580927726, 2.0], [0.5773502691896257, -0.7071067811865475, -0.408248290463863, 3.0], [0, 0, 0, 1.0], ])) np.testing.assert_array_equal(rt_xy_from_known_m, rt_xy_expected) exception_default_params = dict( origin=all_m.isel(channel=[0]), axis_1=all_m.isel(channel=[0, 1]), axis_2=all_m.isel(channel=[0, 2]), axes_name="xy", axis_to_recalculate="y", ) with pytest.raises(ValueError): Rototrans.from_markers(**{ **exception_default_params, **dict(origin=all_m.isel(channel=[0, 1])) }) with pytest.raises(ValueError): Rototrans.from_markers(**{ **exception_default_params, **dict(axis_1=all_m.isel(channel=[0])) }) with pytest.raises(ValueError): Rototrans.from_markers(**{ **exception_default_params, **dict(axis_2=all_m.isel(channel=[0])) }) with pytest.raises(ValueError): Rototrans.from_markers( **{ **exception_default_params, **dict(axis_1=all_m.isel(channel=[0, 1], time=slice(None, 50))), }) with pytest.raises(ValueError): Rototrans.from_markers(**{ **exception_default_params, **dict(axes_name="yyz") }) with pytest.raises(ValueError): Rototrans.from_markers(**{ **exception_default_params, **dict(axes_name="xxz") }) with pytest.raises(ValueError): Rototrans.from_markers(**{ **exception_default_params, **dict(axes_name="zzz") }) with pytest.raises(ValueError): Rototrans.from_markers(**{ **exception_default_params, **dict(axis_to_recalculate="h") })
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(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")
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", )