placecell.maze_helper#
Maze behavior processing for 1D arm analysis.
Functions
|
Split arm traversals into forward/reverse directional segments. |
|
Compute polyline lengths for each zone. |
|
Compute 1D speed along the arm axis using a centered window. |
|
Remove traversals where the animal did not cross from one room to another. |
|
Load behavior graph YAML and return raw polyline waypoints. |
|
Convert zone + arm_position to a concatenated 1D position. |
- placecell.maze_helper.load_graph_polylines(graph_path: Path) dict[str, list[list[float]]]#
Load behavior graph YAML and return raw polyline waypoints.
- Parameters:
graph_path (Path) – Path to YAML file in combined zone format (
zoneskey withtype,points, and optionallyconnectionsper zone).- Returns:
Maps zone name to list of [x, y] waypoints in pixel coords.
- Return type:
dict[str, list[list[float]]]
- placecell.maze_helper.compute_arm_lengths(polylines: dict[str, list[list[float]]], mm_per_pixel: float) dict[str, float]#
Compute polyline lengths for each zone.
- Parameters:
polylines (dict[str, list[list[float]]]) – Maps zone name to list of [x, y] waypoints in pixel coords.
mm_per_pixel (float) – Scale factor for converting pixel distances to mm.
- Returns:
Maps zone name to physical length in mm.
- Return type:
dict[str, float]
- placecell.maze_helper.serialize_arm_position(trajectory: DataFrame, arm_order: list[str], zone_column: str = 'zone', arm_position_column: str = 'arm_position', arm_lengths: dict[str, float] | None = None) DataFrame#
Convert zone + arm_position to a concatenated 1D position.
Filters to arm-only frames and maps each arm’s [0,1] position onto a concatenated 1D axis. When arm_lengths is provided the axis is in physical units (mm) so that each arm spans its real length; otherwise each arm spans exactly 1 unit.
- Parameters:
trajectory (DataFrame) – DataFrame with zone, arm_position, and standard columns.
arm_order (list[str]) – Ordered list of arm zone names.
zone_column (str) – Column containing zone labels.
arm_position_column (str) – Column containing within-arm position (0-1).
arm_lengths (dict[str, float] | None) – Optional dict mapping zone name to physical length. When provided,
pos_1dis in physical units.
- Returns:
Filtered to arm frames only, with new columns
pos_1dandarm_index.- Return type:
pd.DataFrame
- placecell.maze_helper.assign_traversal_direction(trajectory: DataFrame, arm_order: list[str], zone_column: str = 'zone', arm_position_column: str = 'arm_position', direction_threshold: float = 0.5, arm_lengths: dict[str, float] | None = None) tuple[DataFrame, list[str]]#
Split arm traversals into forward/reverse directional segments.
Each contiguous run of frames within the same arm is a “traversal”. Direction is determined by the first
arm_positionvalue: < threshold → forward, >= threshold → reverse.- Parameters:
trajectory (DataFrame) – DataFrame from
serialize_arm_positionwith columnszone_column,arm_position_column,arm_index,pos_1d,frame_index.arm_order (list[str]) – Original arm order (e.g. [“Arm_1”, “Arm_2”, …]).
zone_column (str) – Column with zone labels.
arm_position_column (str) – Column with within-arm position (0-1).
direction_threshold (float) – Position threshold for direction classification.
arm_lengths (dict[str, float] | None) – Optional dict mapping zone name to physical length. When provided,
pos_1dis recomputed in physical units.
- Returns:
effective_arm_order list e.g. [“Arm_1_fwd”, “Arm_1_rev”, …])
- Return type:
tuple of (DataFrame with direction columns and recomputed pos_1d,
- placecell.maze_helper.filter_complete_traversals(trajectory: DataFrame, full_trajectory: DataFrame, arm_order: list[str], zone_column: str = 'zone') DataFrame#
Remove traversals where the animal did not cross from one room to another.
For each traversal, the zone immediately before entering and after leaving the arm is looked up in full_trajectory. A traversal is “complete” when both zones are rooms (not arms) and they differ (i.e. the animal went Room A → Arm → Room B, not Room A → Arm → Room A).
If
traversal_idis not yet present (e.g.split_by_directionis False), traversal boundaries are detected automatically.- Parameters:
trajectory (DataFrame) – Arm-only DataFrame with
frame_indexcolumn (and optionallytraversal_idfromassign_traversal_direction).full_trajectory (DataFrame) – Complete trajectory including room frames, with
frame_indexand zone_column.arm_order (list[str]) – List of arm zone names (anything else is treated as a room).
zone_column (str) – Column containing zone labels in full_trajectory.
- Returns:
Filtered to only complete (room-to-room) traversals.
- Return type:
pd.DataFrame
- placecell.maze_helper.compute_speed_1d(trajectory: DataFrame, *, window_seconds: float, sample_rate_hz: float) DataFrame#
Compute 1D speed along the arm axis using a centered window.
Speed is computed as |delta(pos_1d)| / delta(time) over a symmetric window of actual frame indices, not entry offsets. Because room frames are absent from the arm-only trajectory, consecutive entries can have large frame_index gaps (room visits). Using entry offsets would compute distance/time over artificially long intervals, systematically underestimating speed in frequently-exited arms.
- Parameters:
trajectory (DataFrame) – DataFrame with pos_1d, arm_index, unix_time, frame_index columns. Must be arm-only (output of
serialize_arm_position).window_seconds (float) – Centered window span (seconds).
sample_rate_hz (float) – Trajectory sampling rate, used to convert
window_secondsto a frame count.
- Return type:
pd.DataFrame with
speed_1dcolumn added.