Skip to content

Commit

Permalink
WIP - adding fixture for pose dataset with expected trajectory
Browse files Browse the repository at this point in the history
  • Loading branch information
sfmig committed Aug 27, 2024
1 parent fa0bc94 commit a8ef7ce
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 43 deletions.
75 changes: 74 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,46 @@ def valid_bboxes_array():
"position": position,
"shape": shape,
"confidence": confidence,
"individual_names": ["id_" + str(id) for id in range(n_individuals)],
# "individual_names": ["id_" + str(id) for id in range(n_individuals)],
}


@pytest.fixture
def valid_poses_array_uniform_circular_motion():
# define the shape of the arrays
n_frames, n_individuals, n_space = (10, 2, 2)
n_keypoints = 3 # centroid, left and right

# build a valid array for position
# - for each invidual, the centroid moves in a circular motion
# anticlockwise around the origin.
# - the left and right keypoints are 0.5R and 1.5R away
# from the centroid in the radial direction
# - individual one starts at theta=0
# - individual two starts at theta=pi
position = np.empty((n_frames, n_individuals, n_keypoints, n_space))
theta = np.linspace(0, 2 * np.pi, 10)
keypoint_idx_to_radius = [
(0, 1), # centroid
(1, 0.5), # left
(2, 1.5), # right
]

for i in range(n_individuals):
for kpt_idx, radius in keypoint_idx_to_radius:
# x coord
position[:, i, kpt_idx, 0] = (-1) ** i * radius * np.cos(theta)
# y coord
position[:, i, kpt_idx, 1] = (-1) ** i * radius * np.sin(theta)

# build an array of confidence values, all 0.9
confidence = np.full((n_frames, n_individuals), 0.9)

return {
"position": position,
"confidence": confidence,
# "individual_names": ["id_" + str(id) for id in range(n_individuals)],
"keypoint_names": ["centroid", "left", "right"],
}


Expand Down Expand Up @@ -292,6 +331,40 @@ def valid_bboxes_dataset(
)


@pytest.fixture
def valid_poses_dataset_uniform_circular_motion(
valid_poses_array_uniform_circular_motion,
):
"""Return a valid poses dataset for a uniform circular motion."""
dim_names = MovementDataset.dim_names["poses"]

position_array = valid_poses_array_uniform_circular_motion["position"]
confidence_array = valid_poses_array_uniform_circular_motion["confidence"]
keypoint_names = valid_poses_array_uniform_circular_motion["keypoint_names"]

n_frames, n_individuals, _, _ = position_array.shape

return xr.Dataset(
data_vars={
"position": xr.DataArray(position_array, dims=dim_names),
"confidence": xr.DataArray(confidence_array, dims=dim_names[:-1]),
},
coords={
dim_names[0]: np.arange(n_frames),
dim_names[1]: [f"id_{i}" for i in range(1, n_individuals + 1)],
dim_names[2]: keypoint_names,
dim_names[3]: ["x", "y"],
},
attrs={
"fps": None,
"time_unit": "frames",
"source_software": "test",
"source_file": "test_poses.h5",
"ds_type": "poses",
},
)


@pytest.fixture
def valid_bboxes_dataset_in_seconds(valid_bboxes_dataset):
"""Return a valid bboxes dataset with time in seconds.
Expand Down
84 changes: 44 additions & 40 deletions tests/test_unit/test_kinematics.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,38 +24,41 @@ def _compute_expected_acceleration(position):
return velocity.differentiate("time")


@pytest.mark.parametrize(
"valid_dataset",
[
"valid_poses_dataset",
"valid_poses_dataset_with_nan",
"valid_bboxes_dataset",
"valid_bboxes_dataset_with_nan",
],
)
@pytest.mark.parametrize(
"kinematic_variable_str, expected_kinematic_variable_fn",
[
("displacement", _compute_expected_displacement),
("velocity", _compute_expected_velocity),
("acceleration", _compute_expected_acceleration),
],
)
def test_kinematics(
valid_dataset,
kinematic_variable_str,
expected_kinematic_variable_fn,
request,
):
"""Test displacement computation."""
position = request.getfixturevalue(valid_dataset).position

kinematic_variable = getattr(
kinematics, f"compute_{kinematic_variable_str}"
)(position)
expected_kinematic_variable = expected_kinematic_variable_fn(position)

xr.testing.assert_allclose(kinematic_variable, expected_kinematic_variable)
# @pytest.mark.parametrize(
# "valid_dataset",
# [
# "valid_poses_dataset",
# "valid_poses_dataset_with_nan",
# "valid_bboxes_dataset",
# "valid_bboxes_dataset_with_nan",
# ],
# )
# @pytest.mark.parametrize(
# "kinematic_variable_str, expected_kinematic_variable_fn",
# [
# ("displacement", _compute_expected_displacement),
# ("velocity", _compute_expected_velocity),
# ("acceleration", _compute_expected_acceleration),
# ],
# )
# def test_kinematics(
# valid_dataset,
# kinematic_variable_str,
# expected_kinematic_variable_fn,
# request,
# ):
# """Test displacement computation."""
# position = request.getfixturevalue(valid_dataset).position

# kinematic_variable = getattr(
# kinematics, f"compute_{kinematic_variable_str}"
# )(position)
# expected_kinematic_variable = expected_kinematic_variable_fn(position)

# xr.testing.assert_allclose(kinematic_variable, expected_kinematic_variable)


#### with valid_poses_dataset_with_nan, valid_bboxes_dataset_with_nan tests!


@pytest.mark.parametrize(
Expand All @@ -64,10 +67,10 @@ def test_kinematics(
(
"displacement",
{
"id_0": np.vstack(
0: np.vstack( # first individual
[np.zeros((1, 2)), np.ones((9, 2))]
), # at t=0 displacement is (0,0)
"id_1": np.multiply(
1: np.multiply(
np.vstack([np.zeros((1, 2)), np.ones((9, 2))]),
np.array([1, -1]),
), # n_frames, n_space_dims
Expand All @@ -76,23 +79,24 @@ def test_kinematics(
(
"velocity",
{
"id_0": np.ones((10, 2)),
"id_1": np.multiply(np.ones((10, 2)), np.array([1, -1])),
0: np.ones((10, 2)),
1: np.multiply(np.ones((10, 2)), np.array([1, -1])),
},
),
(
"acceleration",
{
"id_0": np.zeros((10, 2)),
"id_1": np.zeros((10, 2)),
0: np.zeros((10, 2)),
1: np.zeros((10, 2)),
},
),
],
)
def test_kinematics_uniform_linear_motion(
def test_kinematics_bboxes_uniform_linear_motion(
valid_bboxes_dataset,
kinematic_variable,
expected_2D_array_per_individual,
request
):
"""Test kinematics values for uniform linear motion case.
Expand All @@ -112,7 +116,7 @@ def test_kinematics_uniform_linear_motion(

for ind in expected_2D_array_per_individual:
assert np.allclose(
kinematic_variable.sel(individuals=ind).values,
kinematic_variable.isel(individuals=ind).values,
expected_2D_array_per_individual[ind],
)

Expand Down
6 changes: 4 additions & 2 deletions tests/test_unit/test_load_bboxes.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,14 +348,16 @@ def test_extract_confidence_from_via_tracks_df(
@pytest.mark.parametrize(
"df_input, expected_array",
[
# extract from filename
(
"df_input_via_tracks_small",
np.ones((3,)),
), # extract from filename
),
# extract from file_attributes
(
"df_input_via_tracks_small_with_frame_number",
np.array([1, 1, 1]),
), # extract from file_attributes
),
],
)
def test_extract_frame_number_from_via_tracks_df(
Expand Down

0 comments on commit a8ef7ce

Please sign in to comment.