-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement compute_speed
and compute_path_length
#280
base: main
Are you sure you want to change the base?
Conversation
Quality Gate passedIssues Measures |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #280 +/- ##
=======================================
Coverage 99.77% 99.78%
=======================================
Files 15 15
Lines 909 947 +38
=======================================
+ Hits 907 945 +38
Misses 2 2 ☔ View full report in Codecov by Sentry. |
ebae6af
to
129e8c1
Compare
compute_speed
and compute_path_length
92e91f0
to
d089a9c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @niksirbi !
To summarise:
- a few suggestions for wordings, which you're free to take or leave as usual
- start, stop checks: I'm wondering if we should explicitly check these for slicing. While the checks are much more restrictive than xarray, do we need to do so? xarray, for instance, automatically constraints the slicing to the min, max, regardless of whether the provided start, stop values are within or out of range. if we drop our own checks, the relevant tests can then be much simpler
- simplify
_compute_path_length_drop_nan
: hacking withffill
and let xarray'sgroupby
take care of stacking - needs further testing? - simplify tests (reduce parametrisation, test only
id_1
values in nan test) - resolve merge conflicts with main branch
tests/test_unit/test_kinematics.py
Outdated
@pytest.mark.parametrize( | ||
"nan_policy", | ||
["drop", "scale"], # results should be same for both here | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we shouldn't need to test the nan policy here because test_path_length_with_nans()
sufficiently covers this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed
# 9 segments - 1 missing on edge | ||
"centroid": np.sqrt(2) * 8, | ||
# missing mid frames should have no effect | ||
"left": np.sqrt(2) * 9, | ||
"right": np.nan, # all frames missing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
while this is very clear, we could just have np.array([np.sqrt(2) * 8, np.sqrt(2) * 9, np.nan])
expected_array = xr.DataArray( | ||
np.ones((2, 3)) * np.sqrt(2) * 9, | ||
dims=["individuals", "keypoints"], | ||
coords={ | ||
"individuals": position.coords["individuals"], | ||
"keypoints": position.coords["keypoints"], | ||
}, | ||
) | ||
# insert expected path lengths for individual id_1 | ||
for kpt, value in expected_path_lengths_id_1.items(): | ||
target_loc = {"individuals": "id_1", "keypoints": kpt} | ||
expected_array.loc[target_loc] = value | ||
xr.testing.assert_allclose(path_length, expected_array) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
following the above suggestion for using numpy array, we can directly get the path length values of id_1 and compare the numpy arrays ,without comparing the full data array.
Co-authored-by: Chang Huan Lo <[email protected]>
Co-authored-by: Chang Huan Lo <[email protected]>
Co-authored-by: Chang Huan Lo <[email protected]>
Quality Gate passedIssues Measures |
Description
What is this PR
What does this PR do?
It introduces two new functions in the kinematics module:
compute_speed
: quite straightforward to implement, it just returns the norm of velocity, using existingmovement
functionscompute_path_length
: in theory also straightforward, as it should just be the sum of the norms of displacement vectors, but I spent a lot of time debating how to handle missing values. See extensive discussion on zulip.In the end I opted for providing two alternative nan policies, and emitting a warning if too many values are missing. Expand the dropdown below for more details.
compute_path_length() function signatures and docstring
I'm in two minds as to whether we need the
start
andstop
arguments, as the user could easily select a time range usingds.position.sel(time=slice(0, 10))
, before passing the data array tocompute_path_length()
. I've chosen to include them for now, but I'm open to counter-arguments, CC @b-peri.References
Closes #147
How has this PR been tested?
For speed, I used the existing kinematics tests (added "speed" as a parameter) with a bit of modification needed.
Testing for the path length was harder because:
As a result I ended up adding 3 new unit tests to account for all of the above, but suggestion to streamline the tests are welcome.
Is this a breaking change?
No.
Does this PR require an update to the documentation?
API docs should be automatically updated. We might consider mentioning the new functions in some of the examples in the future, but not necessary right now.
Checklist: