Skip to content

Commit bdfa988

Browse files
carlocastoldiniksirbipre-commit-ci[bot]
authored
Add blog post about displacement's API changes (#688)
* Add draft for post about displacement's API changes * remove reference to v0.0.13 Co-authored-by: Niko Sirmpilatze <[email protected]> * improve phrasing in compute_displacement introduction Co-authored-by: Niko Sirmpilatze <[email protected]> * improve wording talking about the PR Co-authored-by: Niko Sirmpilatze <[email protected]> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * compute_backward_displacement Co-authored-by: Niko Sirmpilatze <[email protected]> * improve wording on cart2pol Co-authored-by: Niko Sirmpilatze <[email protected]> * blog: change title and add 1-sentence summary * blog: better explaination of how old implementation worked * blog: headings changes * blog: improve suggestion on how to transition to the new API Co-authored-by: Niko Sirmpilatze <[email protected]> * update date and headings * linkcheck ignore BraiAn --------- Co-authored-by: Niko Sirmpilatze <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent e48a68d commit bdfa988

File tree

4 files changed

+61
-2
lines changed

4 files changed

+61
-2
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
---
2+
blogpost: true
3+
date: November 7, 2025
4+
author: Carlo Castoldi
5+
location: Milan, Italy
6+
category: update
7+
language: English
8+
---
9+
10+
# Replacing displacement vectors for greater clarity
11+
12+
This post introduces recent improvements to how ``movement`` computes displacement vectors, making the definitions more explicit, flexible, and intuitive for users.
13+
14+
## Background
15+
16+
Computing kinematic properties is a core functionality since early versions of `movement`, when they where first introduced by [Chang Huan Lo](https://github.com/lochhh) in [#106](https://github.com/neuroinformatics-unit/movement/pull/106).
17+
For a library dedicated to analysing motion-tracking data, quantifying how far a tracked point moves between consecutive frames is fundamental. This measure underpins subsequent computations, such as the total distance travelled along a path. That's why we introduced the `compute_displacement` function early on, and why it features in our {ref}`compute and visualise kinematics <sphx_glr_examples_compute_kinematics.py>` example<!--#compute-displacement-vectors heading-->.
18+
19+
Its original implementation, however, produced results that were difficult to interpret. For a given individual and keypoint at timestep `t`, displacement was defined as the vector pointing from the previous position at `t-1` to the current position at `t`. This definition is somewhat counter-intuitive: it identifies the last spatial translation used by the keypoint to reach its current position. It indicates where the point _came from_ rather than where it is _going_.
20+
21+
For this reason, during the Hackday at [Open Software Week 2025](https://neuroinformatics.dev/open-software-summer-school/2025/index.html)—and as my first contribution to `movement`—I [volunteered](https://github.com/neuroinformatics-unit/osw25-hackday/issues/16) to develop a more intuitive interface for displacement vectors, under the supervision of [Sofía Miñano](https://github.com/sfmig).
22+
These improvements were introduced in [#657](https://github.com/neuroinformatics-unit/movement/pull/657) through a collaborative effort. The update provides a simpler, well-tested, and better-documented implementation that makes displacement computations easier to understand and use.
23+
24+
![A diagram that shows the comparison between the previous implementation and the updated one.](resources/displacement_old_vs_new.png)
25+
26+
## What's new?
27+
28+
{mod}`kinematics <movement.kinematics>` has two new sister functions:
29+
30+
- {func}`compute_forward_displacement <movement.kinematics.compute_forward_displacement>`, computing the vector defined at time `t` that goes from the position in the current frame to the position in the next frame, at `t+1`.
31+
- {func}`compute_backward_displacement <movement.kinematics.compute_backward_displacement>`, computing the vector defined at time `t` that goes from the position in the current frame to the position in the previous frame, at `t-1`.
32+
33+
These functions replace the previous, more ambiguous `compute_displacement`, which has now been deprecated.
34+
The new API makes the directionality of displacement **explicit**, giving users greater **flexibility**. Depending on the context, one can now choose between forward- or backward-oriented vectors instead of relying on a single implicit definition.
35+
36+
If you need a drop-in replacement for the old behaviour, you can use:
37+
38+
```python
39+
import movement.kinematics as kin
40+
41+
# Instead of:
42+
displacement = kin.compute_displacement(ds.position)
43+
44+
# Use:
45+
displacement = -kin.compute_backward_displacement(ds.position)
46+
```
47+
48+
__Related changes__
49+
50+
We slightly modified the behaviour of vector conversion from Cartesian to polar coordinates. For simplicity and interpretability, {func}`cart2pol <movement.utils.vector.cart2pol>` now always sets the angle `phi` to 0 when the vector's norm `rho` is 0, rather than following the [C standard](https://www.iso.org/standard/29237.html) for [`arctan2`](https://en.wikipedia.org/wiki/Atan2). This change should not affect existing workflows, as a zero-length vector has an undefined direction—meaning it could point in any direction, and assigning `phi = 0` is a safe, neutral choice.
51+
52+
## Reflections
53+
54+
I would like to extend my sincere gratitude to the [Neuroinformatics Unit](https://neuroinformatics.dev/) for fostering an exceptional open environment that has even inspired me to enhance my own projects. Their efforts have motivated me to make [BraiAn](https://silvalab.codeberg.page/BraiAn/) more accessible to inexperienced researchers, to improve its interoperability and to develop automated pipelines for software verification.
55+
56+
I am firmly convinced that bridging the gap between experimental laboratories is crucial for enabling reproducible and comparable results across research groups. I have long _believed_ that the development and adoption of shared standards and widely accepted platforms can facilitate this goal. The Neuroinformatics Unit has not only reinforced my conviction but also _demonstrated_, through their remarkable work, that this vision can be turned into a practical reality.
52.7 KB
Loading

docs/source/conf.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@
191191
"https://opensource.org/license/bsd-3-clause/", # to avoid odd 403 error
192192
"https://www.sainsburywellcome.org/", # Occasional ConnectTimeoutError
193193
"https://www.robots.ox.ac.uk/", # occasional 404s
194+
"https://silvalab.codeberg.page/BraiAn/", # SSLError despite working link
194195
]
195196

196197

examples/compute_kinematics.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,9 @@
198198
ax.set_ylim(980, 1080)
199199
ax.set_xlabel("x (pixels)")
200200
ax.set_ylabel("y (pixels)")
201-
ax.set_title(f"Zoomed in trajectory of {mouse_name}")
201+
ax.set_title(f"Zoomed in forward trajectory of {mouse_name}")
202202
ax.invert_yaxis()
203+
sc.set_clim(8.8, 9.2)
203204
fig.colorbar(sc, ax=ax, label="time (s)")
204205

205206

@@ -250,8 +251,9 @@
250251
ax.set_ylim(980, 1080)
251252
ax.set_xlabel("x (pixels)")
252253
ax.set_ylabel("y (pixels)")
253-
ax.set_title(f"Zoomed in trajectory of {mouse_name}")
254+
ax.set_title(f"Zoomed in backward trajectory of {mouse_name}")
254255
ax.invert_yaxis()
256+
sc.set_clim(8.8, 9.2)
255257
fig.colorbar(sc, ax=ax, label="time (s)")
256258

257259

0 commit comments

Comments
 (0)