def test_angles_creation():
    dims = ("axis", "channel", "time")
    array = Angles()
    np.testing.assert_array_equal(x=array, y=xr.DataArray())
    assert array.dims == dims

    array = Angles(MARKERS_DATA.values, time=MARKERS_DATA.time)
    is_expected_array(array, **EXPECTED_VALUES[57])

    size = 10, 10, 100
    array = Angles.from_random_data(size=size)
    assert array.shape == size
    assert array.dims == dims

    with pytest.raises(ValueError):
        Angles(ANALOGS_DATA)
예제 #2
0
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)
예제 #3
0
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)
예제 #5
0
    def from_random_data(cls,
                         distribution: str = "normal",
                         size: tuple = (3, 1, 100),
                         **kwargs) -> xr.DataArray:
        """
        Create random data from a specified distribution (normal by default) using random walk.

        Arguments:
            distribution: Distribution available in
                [numpy.random](https://docs.scipy.org/doc/numpy-1.14.0/reference/routines.random.html#distributions)
            size: Shape of the desired array
            kwargs: Keyword argument(s) to be passed to numpy.random.`distribution`

        Returns:
            Random rototrans `xarray.DataArray` sampled from a given distribution

        !!! example
            To instantiate a `Rototrans` with some random data sampled from a normal distribution:

            ```python
            from pyomeca import Rototrans

            n_frames = 100
            size = 4, 4, n_frames
            rt = Rototrans.from_random_data(size=size)
            ```

            You can choose any distribution available in
                [numpy.random](https://docs.scipy.org/doc/numpy-1.14.0/reference/routines.random.html#distributions):

            ```python
            rt = Rototrans.from_random_data(distribution="uniform", size=size, low=1, high=10)
            ```
        """
        return Rototrans.from_euler_angles(
            Angles.from_random_data(distribution,
                                    size=(3, 1, size[-1]),
                                    **kwargs),
            "xyz",
        )