coco_pipe.dim_reduction.evaluation.geometry#
Trajectory geometry metrics and smoothing utilities.
This module provides small, generic helpers for analyzing ordered trajectories in embedded spaces. The functions are reducer-agnostic and operate on standard NumPy arrays rather than domain-specific container types.
Functions#
- moving_average
Smooth a one-dimensional timecourse with a valid-mode moving average.
- trajectory_acceleration
Compute instantaneous acceleration magnitude from second-order derivatives.
- trajectory_jerk
Compute instantaneous jerk magnitude (derivative of acceleration).
- trajectory_speed
Compute instantaneous speed from first-order trajectory differences.
- trajectory_curvature
Compute geometric curvature from first- and second-order derivatives.
- trajectory_dispersion
Compute within-group trajectory spread across time.
- trajectory_displacement
Compute displacement from the initial trajectory state across time.
- trajectory_path_length
Compute total or cumulative path length.
- trajectory_separation
Compute time-resolved group separation across time using a selected method.
- trajectory_tortuosity
Compute the ratio between path length and net displacement.
- trajectory_turning_angle
Compute local turning angles between consecutive trajectory segments.
Author: Hamza Abdelhedi (hamza.abdelhedi@umontreal.ca)
Functions#
|
Smooth a one-dimensional array with a valid-mode moving average. |
|
Calculate instantaneous acceleration magnitude. |
|
Calculate instantaneous jerk magnitude (derivative of acceleration). |
|
Calculate instantaneous trajectory speed. |
|
Calculate geometric curvature of a trajectory. |
|
Calculate trajectory path length. |
|
Calculate displacement from the initial state. |
|
Calculate trajectory tortuosity. |
|
Calculate local turning angles between consecutive trajectory segments. |
|
Calculate within-group trajectory dispersion across time. |
|
Calculate time-resolved separation between labeled trajectory groups. |
Compute each point's Euclidean distance from the trajectory's own spatial centroid. |
|
|
Mean distance from the trajectory's own spatial centroid. |
|
Standard deviation of distances from the trajectory's own spatial centroid. |
|
Area under the instantaneous speed curve (trapezoidal integration). |
Module Contents#
- coco_pipe.dim_reduction.evaluation.geometry.moving_average(arr, window)#
Smooth a one-dimensional array with a valid-mode moving average.
- Parameters:
- Returns:
Smoothed array. The output length is
n_samples - window + 1. Ifwindow == 1, a copy of the input is returned.- Return type:
np.ndarray
- Raises:
ValueError – If
arris not one-dimensional, ifwindowis not positive, or ifwindowis larger than the input length.
See also
trajectory_speedFirst-order trajectory dynamics without smoothing.
trajectory_turning_angleLocal directional changes along a trajectory.
Examples
>>> import numpy as np >>> moving_average(np.array([1, 2, 3, 4, 5]), window=3) array([2., 3., 4.])
- coco_pipe.dim_reduction.evaluation.geometry.trajectory_acceleration(traj, dt=1.0)#
Calculate instantaneous acceleration magnitude.
- Parameters:
- Returns:
Acceleration-magnitude timecourse aligned with the input time axis.
- Return type:
np.ndarray of shape (…, n_times)
- Raises:
ValueError – If
trajhas fewer than two dimensions, contains fewer than three time points, or ifdt <= 0.
See also
trajectory_speedFirst-order trajectory dynamics.
trajectory_curvatureGeometric bending of a trajectory.
trajectory_turning_angleLocal directional changes between segments.
Examples
>>> import numpy as np >>> t = np.linspace(0.0, 2.0, 3) >>> traj = np.stack([t**2, np.zeros_like(t)], axis=1) >>> trajectory_acceleration(traj, dt=1.0).shape (3,)
- coco_pipe.dim_reduction.evaluation.geometry.trajectory_jerk(traj, dt=1.0)#
Calculate instantaneous jerk magnitude (derivative of acceleration).
Jerk is the third derivative of position with respect to time, or equivalently the first derivative of the acceleration vector. A sudden spike in jerk means the trajectory “snapped” into a new movement, often correlating with discrete cognitive decisions or abrupt state transitions.
- Parameters:
- Returns:
Jerk-magnitude timecourse aligned with the input time axis.
- Return type:
np.ndarray of shape (…, n_times)
- Raises:
ValueError – If
trajhas fewer than two dimensions, contains fewer than four time points, or ifdt <= 0.
See also
trajectory_accelerationSecond-order trajectory dynamics.
trajectory_speedFirst-order trajectory dynamics.
trajectory_curvatureGeometric bending of a trajectory.
Examples
>>> import numpy as np >>> t = np.linspace(0.0, 3.0, 4) >>> traj = np.stack([t**3, np.zeros_like(t)], axis=1) >>> trajectory_jerk(traj, dt=1.0).shape (4,)
- coco_pipe.dim_reduction.evaluation.geometry.trajectory_speed(traj, dt=1.0, time=None)#
Calculate instantaneous trajectory speed.
- Parameters:
traj (np.ndarray of shape (..., n_times, n_dims)) – Trajectory array. The second-to-last axis is interpreted as time and the last axis as coordinates.
dt (float, default=1.0) – Uniform time step between consecutive samples. Ignored when
timeis provided.time (np.ndarray of shape (n_times,), optional) – Real timestamps (e.g. milliseconds) for non-uniform sampling. When provided, per-step
dtvalues are derived fromnp.diff(time)and the output has shape(..., n_times - 1)— no padding is applied because the associated time axis istime[:-1].
- Returns:
time=None: shape(..., n_times), last value padded.timeprovided: shape(..., n_times - 1), no padding.
- Return type:
np.ndarray
- Raises:
ValueError – If
trajhas fewer than two dimensions, fewer than two time points,dt <= 0(uniform mode), ortimelength mismatchestraj.
Notes
Speed is the Euclidean norm of the first difference divided by the time step.
See also
trajectory_accelerationSecond-order trajectory dynamics.
trajectory_path_lengthTotal or cumulative traveled distance.
trajectory_displacementDistance from the initial state across time.
Examples
>>> import numpy as np >>> traj = np.array([[0.0, 0.0], [1.0, 0.0], [2.0, 0.0]]) >>> trajectory_speed(traj) array([1., 1., 1.]) >>> trajectory_speed(traj, time=np.array([0.0, 100.0, 250.0])) array([0.01 , 0.00666667])
- coco_pipe.dim_reduction.evaluation.geometry.trajectory_curvature(traj, method='cosine')#
Calculate geometric curvature of a trajectory.
- Parameters:
traj (np.ndarray of shape (..., n_times, n_dims)) – Trajectory array. The second-to-last axis is interpreted as time and the last axis as coordinates.
method ({"cosine", "gradient"}, default="cosine") –
Formula used to compute curvature.
"cosine"— discrete turning-angle formula: the angle between consecutive step vectors divided by the step length. Output shape is(..., n_times - 2)because two differencing operations are required."gradient"— continuous formula using first and second derivatives:sqrt(||v||^2 ||a||^2 - (v·a)^2) / ||v||^3. Assumes uniformly spaced samples. Output shape is(..., n_times).
- Returns:
method="cosine": shape(..., n_times - 2)method="gradient": shape(..., n_times)
- Return type:
np.ndarray
- Raises:
ValueError – If
trajhas fewer than two dimensions, insufficient time points, or an unsupportedmethodis given.
See also
trajectory_turning_angleDiscrete local turning angles (no curvature scaling).
trajectory_tortuosityPath inefficiency relative to net displacement.
trajectory_speedFirst-order trajectory dynamics.
Examples
>>> import numpy as np >>> t = np.linspace(0, 2 * np.pi, 100) >>> traj = np.stack([np.cos(t), np.sin(t)], axis=1) >>> trajectory_curvature(traj, method="gradient").shape (100,) >>> trajectory_curvature(traj, method="cosine").shape (98,)
- coco_pipe.dim_reduction.evaluation.geometry.trajectory_path_length(traj, *, cumulative=False)#
Calculate trajectory path length.
- Parameters:
traj (np.ndarray of shape (..., n_times, n_dims)) – Trajectory array. The second-to-last axis is interpreted as time and the last axis as coordinates.
cumulative (bool, default=False) – If
True, return cumulative path length aligned with the input time axis. Otherwise return total path length for each trajectory.
- Returns:
Total path length with shape
(...)whencumulative=False, or cumulative path length with shape(..., n_times)whencumulative=True.- Return type:
np.ndarray
Notes
NaN-valued steps are skipped in both the total and cumulative modes so that a single missing coordinate does not invalidate the whole result.
See also
trajectory_displacementDistance from the initial state across time.
trajectory_tortuosityRatio of path length to net displacement.
trajectory_speedFirst-order local motion magnitude.
Examples
>>> import numpy as np >>> traj = np.array([[0.0, 0.0], [1.0, 0.0], [2.0, 0.0]]) >>> trajectory_path_length(traj) np.float64(2.0)
- coco_pipe.dim_reduction.evaluation.geometry.trajectory_displacement(traj, *, final=False)#
Calculate displacement from the initial state.
- Parameters:
traj (np.ndarray of shape (..., n_times, n_dims)) – Trajectory array. The second-to-last axis is interpreted as time and the last axis as coordinates.
final (bool, default=False) – If
False(default), return the displacement timecourse from the first point at every time index — shape(..., n_times). IfTrue, return only the scalar net displacement from the first to the last point — shape(...).
- Returns:
final=False: shape(..., n_times)final=True: shape(...)
- Return type:
np.ndarray
See also
trajectory_path_lengthTotal or cumulative traveled distance.
trajectory_tortuosityRatio of traveled distance to final displacement.
Examples
>>> import numpy as np >>> traj = np.array([[0.0, 0.0], [1.0, 0.0], [1.0, 1.0]]) >>> trajectory_displacement(traj) array([0. , 1. , 1.41421356]) >>> trajectory_displacement(traj, final=True) np.float64(1.4142135623730951)
- coco_pipe.dim_reduction.evaluation.geometry.trajectory_tortuosity(traj, eps=1e-08)#
Calculate trajectory tortuosity.
Tortuosity is defined as total path length divided by net displacement from the initial to the final state.
- Parameters:
- Returns:
Tortuosity for each trajectory. Stationary trajectories return
1.0; trajectories with nonzero path length but near-zero net displacement returnnp.inf.- Return type:
np.ndarray of shape (…)
See also
trajectory_path_lengthTotal traveled distance along the path.
trajectory_displacementNet displacement from start to end.
trajectory_curvatureLocal geometric bending.
Examples
>>> import numpy as np >>> traj = np.array([[0.0, 0.0], [1.0, 0.0], [2.0, 0.0]]) >>> trajectory_tortuosity(traj) np.float64(1.0)
- coco_pipe.dim_reduction.evaluation.geometry.trajectory_turning_angle(traj)#
Calculate local turning angles between consecutive trajectory segments.
- Parameters:
traj (np.ndarray of shape (..., n_times, n_dims)) – Trajectory array. The second-to-last axis is interpreted as time and the last axis as coordinates.
- Returns:
Turning-angle timecourse in radians. The output is shorter than the input by two points because each angle requires one predecessor and one successor segment.
- Return type:
np.ndarray of shape (…, n_times - 2)
See also
trajectory_curvatureCurvature computed from turning angles (cosine method).
trajectory_speedLocal motion magnitude.
trajectory_path_lengthTotal or cumulative traveled distance.
Examples
>>> import numpy as np >>> traj = np.array([[0.0, 0.0], [1.0, 0.0], [1.0, 1.0]]) >>> trajectory_turning_angle(traj) array([1.57079633])
- coco_pipe.dim_reduction.evaluation.geometry.trajectory_dispersion(traj, labels=None)#
Calculate within-group trajectory dispersion across time.
- Parameters:
- Returns:
Global dispersion timecourse when
labelsis omitted, otherwise a mapping from label to dispersion timecourse.- Return type:
See also
trajectory_separationUnified separation entrypoint.
trajectory_separationUse
method="within_between_ratio"for normalized separation.
Examples
>>> import numpy as np >>> traj = np.zeros((2, 3, 2)) >>> traj[1, :, 0] = 1.0 >>> trajectory_dispersion(traj) array([0.5, 0.5, 0.5])
- coco_pipe.dim_reduction.evaluation.geometry.trajectory_separation(traj, labels, method='centroid', **kwargs)#
Calculate time-resolved separation between labeled trajectory groups.
- Parameters:
traj (np.ndarray of shape (n_trials, n_times, n_dims)) – Trajectory tensor containing one trajectory per trial.
labels (np.ndarray of shape (n_trials,)) – Class label for each trial.
method ({"centroid", "within_between_ratio", "mahalanobis",) – “distributional”, “margin”}, default=”centroid” Separation definition to compute.
**kwargs (dict) – Additional keyword arguments forwarded to the selected separation method.
- Returns:
Mapping from label pairs to separation timecourses of shape
(n_times,).- Return type:
- Raises:
ValueError – If the inputs are invalid or if an unsupported separation method is requested.
Notes
This is the high-level separation entrypoint for trajectory-group comparison. It dispatches to the more specific separation primitives in this module.
Supported methods:
"centroid": Euclidean distance between label centroids."within_between_ratio": Between-centroid distance normalized by within-group dispersion."mahalanobis": Covariance-aware centroid separation."distributional": Energy-distance separation between trial clouds."margin": Nearest-cross minus nearest-within margin separation.
See also
trajectory_dispersionWithin-group spread used by some separation methods.
Examples
>>> import numpy as np >>> traj = np.zeros((4, 5, 2)) >>> labels = np.array(["A", "A", "B", "B"]) >>> sep = trajectory_separation(traj, labels, method="centroid") >>> list(sep.keys()) [('A', 'B')]
- coco_pipe.dim_reduction.evaluation.geometry.trajectory_distance_from_center(traj)#
Compute each point’s Euclidean distance from the trajectory’s own spatial centroid.
The centroid is the mean position across all time points of a single trajectory. This is distinct from
trajectory_dispersion(), which measures spread across trials at each fixed time point.- Parameters:
traj (np.ndarray of shape (..., n_times, n_dims)) – Trajectory array. The second-to-last axis is interpreted as time and the last axis as coordinates.
- Returns:
Per-point distance from the temporal centroid.
- Return type:
np.ndarray of shape (…, n_times)
See also
trajectory_cohesionMean of this timecourse (compactness scalar).
trajectory_intra_spreadStd of this timecourse (variability scalar).
trajectory_dispersionAcross-trial spread at each time point.
Examples
>>> import numpy as np >>> traj = np.array([[0.0, 0.0], [2.0, 0.0], [0.0, 0.0]]) >>> trajectory_distance_from_center(traj) array([0.66666667, 1.33333333, 0.66666667])
- coco_pipe.dim_reduction.evaluation.geometry.trajectory_cohesion(traj)#
Mean distance from the trajectory’s own spatial centroid.
A small value means the trajectory stays near its average position (compact loop or oscillation); a large value means it sweeps far from its center.
- Parameters:
traj (np.ndarray of shape (..., n_times, n_dims)) – Trajectory array. The second-to-last axis is interpreted as time and the last axis as coordinates.
- Returns:
Cohesion scalar for each trajectory in the batch.
- Return type:
np.ndarray of shape (…)
See also
trajectory_distance_from_centerFull per-point timecourse.
trajectory_intra_spreadComplementary variability measure.
Examples
>>> import numpy as np >>> traj = np.array([[0.0, 0.0], [2.0, 0.0], [0.0, 0.0]]) >>> trajectory_cohesion(traj) np.float64(0.888...)
- coco_pipe.dim_reduction.evaluation.geometry.trajectory_intra_spread(traj)#
Standard deviation of distances from the trajectory’s own spatial centroid.
Measures how variable the distance-from-center is across time: a trajectory that uniformly orbits its centroid has low intra-spread; one that starts close and ends far away has high intra-spread.
Not to be confused with
trajectory_separation(), which compares the centroids of two separate trial groups.- Parameters:
traj (np.ndarray of shape (..., n_times, n_dims)) – Trajectory array. The second-to-last axis is interpreted as time and the last axis as coordinates.
- Returns:
Intra-spread scalar for each trajectory in the batch.
- Return type:
np.ndarray of shape (…)
See also
trajectory_distance_from_centerFull per-point timecourse.
trajectory_cohesionComplementary mean measure.
trajectory_separationBetween-group separation (different concept).
Examples
>>> import numpy as np >>> traj = np.array([[0.0, 0.0], [2.0, 0.0], [0.0, 0.0]]) >>> trajectory_intra_spread(traj) np.float64(0.314...)
- coco_pipe.dim_reduction.evaluation.geometry.trajectory_auc_speed(traj, dt=1.0, time=None)#
Area under the instantaneous speed curve (trapezoidal integration).
Integrates speed over time, giving a measure of total kinetic activity that weights fast periods more heavily than
trajectory_path_length(). Units are[spatial_units · time_units]whentimeis provided, or[spatial_units · samples]with uniformdt=1.- Parameters:
traj (np.ndarray of shape (..., n_times, n_dims)) – Trajectory array. The second-to-last axis is interpreted as time and the last axis as coordinates.
dt (float, default=1.0) – Uniform time step. Ignored when
timeis provided.time (np.ndarray of shape (n_times,), optional) – Real timestamps for non-uniform integration. When provided, per-step
dtvalues are derived fromnp.diff(time)and the speed is integrated againsttime[:-1].
- Returns:
AUC-speed scalar for each trajectory in the batch.
- Return type:
np.ndarray of shape (…)
- Raises:
ValueError – If
trajhas fewer than two time points,dt <= 0(uniform mode), ortimelength mismatchestraj.
See also
trajectory_speedPer-step speed timecourse.
trajectory_path_lengthTotal path length (uniform speed weighting).
Examples
>>> import numpy as np >>> traj = np.array([[0.0, 0.0], [1.0, 0.0], [2.0, 0.0]]) >>> trajectory_auc_speed(traj, dt=1.0) np.float64(1.0) >>> trajectory_auc_speed(traj, time=np.array([0.0, 100.0, 200.0])) np.float64(100.0)