Skip to content

Commit

Permalink
Reversed changes to compute_polar_coordinates.py and implemented fi…
Browse files Browse the repository at this point in the history
…nal feedback
  • Loading branch information
b-peri committed Oct 4, 2024
1 parent b2de46a commit 268d395
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 34 deletions.
24 changes: 13 additions & 11 deletions examples/compute_polar_coordinates.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
from matplotlib import pyplot as plt

from movement import sample_data
from movement.analysis.kinematics import compute_head_direction_vector
from movement.io import load_poses
from movement.utils.vector import cart2pol, pol2cart

Expand Down Expand Up @@ -49,14 +48,20 @@
# To demonstrate how polar coordinates can be useful in behavioural analyses,
# we will compute the head vector of the mouse.
#
# In ``movement``, head vector is defined as the vector perpendicular to the
# line connecting two symmetrical keypoints on either side of the head (usually
# the ears), pointing forwards. (See :func:`here\
# <movement.analysis.kinematics.compute_forward_vector>` for a more
# detailed explanation).
# We define it as the vector from the midpoint between the ears to the snout.

head_vector = compute_head_direction_vector(position, "left_ear", "right_ear")
# compute the midpoint between the ears
midpoint_ears = position.sel(keypoints=["left_ear", "right_ear"]).mean(
dim="keypoints"
)

# compute the head vector
head_vector = position.sel(keypoints="snout") - midpoint_ears

# drop the keypoints dimension
# (otherwise the `head_vector` data array retains a `snout` keypoint from the
# operation above)
head_vector = head_vector.drop_vars("keypoints")

# %%
# Visualise the head trajectory
Expand All @@ -67,12 +72,9 @@
# We can start by plotting the trajectory of the midpoint between the ears. We
# will refer to this as the head trajectory.

midpoint_ears = position.sel(keypoints=["left_ear", "right_ear"]).mean(
dim="keypoints"
)
fig, ax = plt.subplots(1, 1)
mouse_name = ds.individuals.values[0]

fig, ax = plt.subplots(1, 1)
sc = ax.scatter(
midpoint_ears.sel(individuals=mouse_name, space="x"),
midpoint_ears.sel(individuals=mouse_name, space="y"),
Expand Down
46 changes: 24 additions & 22 deletions movement/analysis/kinematics.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,31 +177,13 @@ def compute_forward_vector(
right_keypoint: str,
camera_view: Literal["top_down", "bottom_up"] = "top_down",
):
"""Compute a 2D forward vector given two left-right symmetrical keypoints.
"""Compute a 2D forward vector given two left-right symmetric keypoints.
The forward vector is computed as a vector perpendicular to the
line connecting two symmetrical keypoints on either side of the body
(i.e., symmetrical relative to the mid-sagittal plane), and pointing
forwards (in the rostral direction). A top-down or bottom-up view of the
animal is assumed.
To determine the forward direction of the animal, we need to specify
(1) the right-to-left direction of the animal and (2) its upward direction.
We determine the right-to-left direction via the input left and right
keypoints. The upwards direction, in turn, can be determined by passing the
``camera_view`` argument with either ``"top_down"`` or ``"bottom_up"``. If
the camera view is specified as being ``top_down``, or if no additional
information is provided, we assume that the upwards direction matches that
of the vector [0, 0, -1]. If the camera view is ``bottom_up``, the upwards
direction is assumed to be given by [0, 0, 1]. For both cases, we assume
that position values are expressed in the image coordinate system (where
the positive X-axis is oriented to the right, the positive Y-axis faces
downwards, and positive Z-axis faces away from the person viewing the
screen).
If one of the required pieces of information is missing for a frame (e.g.,
the left keypoint is not visible), then the computed head direction vector
is set to NaN.
animal is assumed (see Notes).
Parameters
----------
Expand All @@ -227,6 +209,26 @@ def compute_forward_vector(
dimensions matching the input data array, but without the
``keypoints`` dimension.
Notes
-----
To determine the forward direction of the animal, we need to specify
(1) the right-to-left direction of the animal and (2) its upward direction.
We determine the right-to-left direction via the input left and right
keypoints. The upwards direction, in turn, can be determined by passing the
``camera_view`` argument with either ``"top_down"`` or ``"bottom_up"``. If
the camera view is specified as being ``"top_down"``, or if no additional
information is provided, we assume that the upwards direction matches that
of the vector ``[0, 0, -1]``. If the camera view is ``"bottom_up"``, the
upwards direction is assumed to be given by ``[0, 0, 1]``. For both cases,
we assume that position values are expressed in the image coordinate
system (where the positive X-axis is oriented to the right, the positive
Y-axis faces downwards, and positive Z-axis faces away from the person
viewing the screen).
If one of the required pieces of information is missing for a frame (e.g.,
the left keypoint is not visible), then the computed head direction vector
is set to NaN.
"""
# Validate input data
_validate_type_data_array(data)
Expand All @@ -241,7 +243,7 @@ def compute_forward_vector(
if len(data.space) != 2:
raise log_error(
ValueError,
"Input data must have 2 (and only 2) spatial dimensions, but "
"Input data must have exactly 2 spatial dimensions, but "
f"currently has {len(data.space)}.",
)

Expand Down Expand Up @@ -290,7 +292,7 @@ def compute_head_direction_vector(
This function is an alias for :func:`compute_forward_vector()\
<movement.analysis.kinematics.compute_forward_vector>`. For more
detailed information on how the head direction vector is computed,
please refer to the documentation for this function.
please refer to the documentation for that function.
Parameters
----------
Expand Down
2 changes: 1 addition & 1 deletion tests/test_unit/test_kinematics.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ def test_compute_forward_vector(valid_data_array_for_forward_vector):
(
"invalid_spatial_dimensions_for_forward_vector",
ValueError,
"must have 2 (and only 2) spatial dimensions",
"must have exactly 2 spatial dimensions",
["left_ear", "right_ear"],
),
(
Expand Down

0 comments on commit 268d395

Please sign in to comment.