neuroinformatics-unit / movement

Python tools for analysing body movements across space and time
http://movement.neuroinformatics.dev
BSD 3-Clause "New" or "Revised" License
77 stars 7 forks source link

Kinetic Energy Decomposition #228

Open niksirbi opened 1 week ago

niksirbi commented 1 week ago

This feature was suggested by @dimokaramanlis, who finds it useful in analysing his pose tracking data.

Definition

If we consider each individual's set of keypoints (pose) as a classical system of bodies in physics (with unit masses for simplicity), we could compute the total kinetic energy of that system as:

$$ K{total} = \sum{i} \frac{1}{2} || \mathbf{v}_i(t) ||^2 $$

Where $\mathbf{v}_i(t) = [v_i^x(t), v_i^y(t)]$ is the 2D (x,y) velocity vector of the $i_{th}$ keypoint at time $t$.

We can decompose $K_{total}$ into two components:

  1. The translational kinetic energy $K_{trans}$ which is associated with the motion of the centre-of-mass. We can get this if we first compute the centre-of-mass velocity $\mathbf{V}(t)$ (across $M$ keypoints).

$$ \mathbf{V}(t) = \frac{1}{M} \sum_i \mathbf{v}_i(t) $$

$$ K_\text{trans} = \frac{1}{2} ||\mathbf{V}(t)||^2 $$

  1. The rotational kinetic energy $K_{rot}$ which is associated with the motion relative to the centre-of-mass. We can derive this simply as the remaining kinetic energy:

$$ K{rot} = K{total} - K_{trans} $$

Applications

Implementation

This should be doable in a few lines of xarray code, with our existing dataset structure. The output could be a DataArray with dimensions time, individuals, and energy, where energy can have two coordinates - translational and rotational.

It will be facilitated by implementing a norm() function in utils/vector.py, which @sfmig was planning to do anyway.

Considerations

niksirbi commented 1 week ago

Two additional considerations brought up by Dimos:

sfmig commented 1 week ago

I like this idea! And the suggestion of computing these at the individual level or at the collective level (for a flock) could be cool.

But maybe there are metrics that are more informative for a collective. From my experience with flocking behaviour, common metrics relate to how aligned are the velocity vectors of the individuals, e.g. with the average velocity of the flock or with their neighbours' velocity vectors (see Fig1 here for a metric along these lines). Note that with kinetic energy you loose the alignment info. Maybe we could open a new issue on implementing metrics for flocks - what do you think?

I think the kinetic energy computation per individual is not currently a very demanded feature, but as you say should be easy to implement, and seems useful for analysis. Maybe a good one to get users to try out and report back?

niksirbi commented 1 week ago

Yeah I think metrics for flocking behaviour are interesting in their own right, but that should be a separate issue.

For this one, let's focus on computing the kinetic energy per individual only. I agree it's not a high priority, but should be very quick as it's a very well-defined task (famous last words). It would be nice to have an additional metric in the kinematics module.