Analysis

╔══════════════════════════════════════════════════════════╗ ║ analysis « post-simulation metrics & plotting » ║ ╚══════════════════════════════════════════════════════════╝

Functions for computing exploration rate, food-collection efficiency, step-size distributions, movement-type classification, and drift-angle statistics from simulation results.

satyre.analysis.exploration_rate_ellipse(head_x, head_y, tail_x, tail_y, dt=1.0)[source]

Compute orientation-dependent exploration rate.

Superimposes the fly body (modelled as the quadrilateral between successive head/tail positions) and sums the non-overlapping area per time step.

Parameters:
Return type:

ndarray[tuple[Any, ...], dtype[TypeVar(_ScalarT, bound= generic)]]

Returns:

Array of shape (n_trials,) giving the total area covered per trial (mm²).

satyre.analysis.exploration_rate_disc(step_sizes, body_width=2.0, dt=1.0)[source]

Compute orientation-independent exploration rate.

Replaces the elliptical fly body with a circle of equal surface area, so each step sweeps a rectangle of width body_width × step length.

Parameters:
  • step_sizes (ndarray[tuple[Any, ...], dtype[TypeVar(_ScalarT, bound= generic)]]) – Step-size array, shape (n_trials, n_steps).

  • body_width (float) – Diameter of the equivalent disc (mm).

  • dt (float) – Time interval between steps (seconds).

Return type:

ndarray[tuple[Any, ...], dtype[TypeVar(_ScalarT, bound= generic)]]

Returns:

Array of shape (n_trials,) giving the total area covered per trial (mm²).

satyre.analysis.summarise_food_collected(results)[source]

Compute summary statistics for food-collection data.

Parameters:

results (dict[str, ndarray[tuple[Any, ...], dtype[TypeVar(_ScalarT, bound= generic)]]]) – Dictionary returned by simulate_multiple() (must contain key 'food_found').

Return type:

dict[str, float]

Returns:

Dictionary with keys 'mean', 'median', 'std', 'ci_lower', 'ci_upper' (95 % bootstrap CI), and 'n'.

satyre.analysis.step_size_distribution(step_sizes)[source]

Compute descriptive statistics of step-size arrays.

Parameters:

step_sizes (ndarray[tuple[Any, ...], dtype[TypeVar(_ScalarT, bound= generic)]]) – Array of shape (n_trials, n_steps) containing Euclidean step lengths.

Return type:

dict[str, ndarray[tuple[Any, ...], dtype[TypeVar(_ScalarT, bound= generic)]] | float]

Returns:

Dictionary with 'mean_per_trial', 'median_per_trial', 'grand_mean', 'grand_median', and the flattened 'all_steps' (NaN-stripped).

satyre.analysis.classify_movements(performed_pms, velocity_array, *, trans_threshold=0.5, rot_threshold=1.0)[source]

Classify each PM step as stationary, translational, or rotational.

Parameters:
  • performed_pms (ndarray[tuple[Any, ...], dtype[TypeVar(_ScalarT, bound= generic)]]) – 1-D integer array of PM indices visited during a trial.

  • velocity_array (ndarray[tuple[Any, ...], dtype[TypeVar(_ScalarT, bound= generic)]]) – (N, 3) velocity look-up table [thrust, slip, yaw].

  • trans_threshold (float) – Combined thrust + slip speed below which the step is considered stationary (mm s⁻¹).

  • rot_threshold (float) – Yaw speed above which the step is rotational (rad s⁻¹).

Returns:

  • 'labels' — list of strings ('stationary', 'translational', 'rotational').

  • 'proportions'[% stationary, % translational, % rotational].

Return type:

dict[str, ndarray[tuple[Any, ...], dtype[TypeVar(_ScalarT, bound= generic)]] | list[float]]

Area covered

╔══════════════════════════════════════════════════════════╗ ║ area_covered « exploration-rate computation » ║ ╚══════════════════════════════════════════════════════════╝

Compute the unique area swept by the fly’s body (or by a disc of equal area) per unit time, following the analytical method described in the manuscript.

satyre.analysis.area_covered.exploration_rate_ellipse(head_x, head_y, tail_x, tail_y, dt=1.0)[source]

Compute orientation-dependent exploration rate.

Superimposes the fly body (modelled as the quadrilateral between successive head/tail positions) and sums the non-overlapping area per time step.

Parameters:
Return type:

ndarray[tuple[Any, ...], dtype[TypeVar(_ScalarT, bound= generic)]]

Returns:

Array of shape (n_trials,) giving the total area covered per trial (mm²).

satyre.analysis.area_covered.exploration_rate_disc(step_sizes, body_width=2.0, dt=1.0)[source]

Compute orientation-independent exploration rate.

Replaces the elliptical fly body with a circle of equal surface area, so each step sweeps a rectangle of width body_width × step length.

Parameters:
  • step_sizes (ndarray[tuple[Any, ...], dtype[TypeVar(_ScalarT, bound= generic)]]) – Step-size array, shape (n_trials, n_steps).

  • body_width (float) – Diameter of the equivalent disc (mm).

  • dt (float) – Time interval between steps (seconds).

Return type:

ndarray[tuple[Any, ...], dtype[TypeVar(_ScalarT, bound= generic)]]

Returns:

Array of shape (n_trials,) giving the total area covered per trial (mm²).

Food found

╔══════════════════════════════════════════════════════════╗ ║ food_found « foraging-efficiency summary » ║ ╚══════════════════════════════════════════════════════════╝

satyre.analysis.food_found.summarise_food_collected(results)[source]

Compute summary statistics for food-collection data.

Parameters:

results (dict[str, ndarray[tuple[Any, ...], dtype[TypeVar(_ScalarT, bound= generic)]]]) – Dictionary returned by simulate_multiple() (must contain key 'food_found').

Return type:

dict[str, float]

Returns:

Dictionary with keys 'mean', 'median', 'std', 'ci_lower', 'ci_upper' (95 % bootstrap CI), and 'n'.

Step size

╔══════════════════════════════════════════════════════════╗ ║ step_size « step-length distribution analysis » ║ ╚══════════════════════════════════════════════════════════╝

satyre.analysis.step_size.step_size_distribution(step_sizes)[source]

Compute descriptive statistics of step-size arrays.

Parameters:

step_sizes (ndarray[tuple[Any, ...], dtype[TypeVar(_ScalarT, bound= generic)]]) – Array of shape (n_trials, n_steps) containing Euclidean step lengths.

Return type:

dict[str, ndarray[tuple[Any, ...], dtype[TypeVar(_ScalarT, bound= generic)]] | float]

Returns:

Dictionary with 'mean_per_trial', 'median_per_trial', 'grand_mean', 'grand_median', and the flattened 'all_steps' (NaN-stripped).

Movement types

╔══════════════════════════════════════════════════════════╗ ║ movement_types « stationary / translational / rot » ║ ╚══════════════════════════════════════════════════════════╝

Classify each prototypical-movement step into stationary, translational, or rotational based on velocity thresholds.

satyre.analysis.movement_types.classify_movements(performed_pms, velocity_array, *, trans_threshold=0.5, rot_threshold=1.0)[source]

Classify each PM step as stationary, translational, or rotational.

Parameters:
  • performed_pms (ndarray[tuple[Any, ...], dtype[TypeVar(_ScalarT, bound= generic)]]) – 1-D integer array of PM indices visited during a trial.

  • velocity_array (ndarray[tuple[Any, ...], dtype[TypeVar(_ScalarT, bound= generic)]]) – (N, 3) velocity look-up table [thrust, slip, yaw].

  • trans_threshold (float) – Combined thrust + slip speed below which the step is considered stationary (mm s⁻¹).

  • rot_threshold (float) – Yaw speed above which the step is rotational (rad s⁻¹).

Returns:

  • 'labels' — list of strings ('stationary', 'translational', 'rotational').

  • 'proportions'[% stationary, % translational, % rotational].

Return type:

dict[str, ndarray[tuple[Any, ...], dtype[TypeVar(_ScalarT, bound= generic)]] | list[float]]