Skip to content

pose

KinematicPose

A snapshot of joint angles defining a static fly pose.

Parameters:

Name Type Description Default
path PathLike | None

Path to YAML file containing joint angles and metadata. Either this or joint_angles_rad_dict must be provided, but not both.

None
joint_angles_rad_dict dict[str, float] | None

Dictionary mapping joint DoF names to angles in radians. Either this or path must be provided, but not both.

None
axis_order AxisOrder | str | list[RotationAxis | str] | None

The AxisOrder of the provided angles if initializing from joint_angles_rad_dict (required). If initializing from path, this attribute must not be specified because the axis order will be loaded from the file.

None
mirror_left2right bool

If True, mirror left-side joint angles to right-side when not provided.

True

Example:

pose = KinematicPose(path="neutral.yaml", mirror_left2right=True)
# then use `pose.joint_angles_lookup_rad`
Source code in src/flygym/compose/pose.py
class KinematicPose:
    """A snapshot of joint angles defining a static fly pose.

    Args:
        path:
            Path to YAML file containing joint angles and metadata. Either this or
            `joint_angles_rad_dict` must be provided, but not both.
        joint_angles_rad_dict:
            Dictionary mapping joint DoF names to angles in radians. Either this or
            `path` must be provided, but not both.
        axis_order:
            The AxisOrder of the provided angles if initializing from
            `joint_angles_rad_dict` (required). If initializing from `path`, this
            attribute must not be specified because the axis order will be loaded from
            the file.
        mirror_left2right:
            If True, mirror left-side joint angles to right-side when not provided.

    Example:

        pose = KinematicPose(path="neutral.yaml", mirror_left2right=True)
        # then use `pose.joint_angles_lookup_rad`
    """

    def __init__(
        self,
        *,
        path: PathLike | None = None,
        joint_angles_rad_dict: dict[str, float] | None = None,
        axis_order: AxisOrder | str | list[RotationAxis | str] | None = None,
        mirror_left2right: bool = True,
    ) -> None:
        if joint_angles_rad_dict is not None and path is None:
            if axis_order is None:
                raise ValueError(
                    "When initializing from `joint_angles_rad_dict`, axis_order must "
                    "also be provided."
                )
            axis_order = AxisOrder(axis_order)
        elif path is not None and joint_angles_rad_dict is None:
            if axis_order is not None:
                raise ValueError(
                    "When initializing from `path`, `axis_order` should not be "
                    "provided because it will be loaded from the pose file."
                )
            joint_angles_rad_dict, axis_order = _load_pose_yaml(path)
        else:
            raise ValueError(
                "Either joint_angles_rad_dict or path must be provided, but not both."
            )

        joint_angles_rad_dict = dict(joint_angles_rad_dict)  # don't mutate caller dict
        if mirror_left2right:
            _mirror_pose_left2right_in_place(joint_angles_rad_dict)

        self.axis_order = axis_order
        self.joint_angles_lookup_rad = joint_angles_rad_dict

    def copy(self) -> "KinematicPose":
        """Return a deep copy of this pose."""
        return KinematicPose(
            joint_angles_rad_dict=self.joint_angles_lookup_rad.copy(),
            axis_order=self.axis_order,
        )

copy()

Return a deep copy of this pose.

Source code in src/flygym/compose/pose.py
def copy(self) -> "KinematicPose":
    """Return a deep copy of this pose."""
    return KinematicPose(
        joint_angles_rad_dict=self.joint_angles_lookup_rad.copy(),
        axis_order=self.axis_order,
    )

KinematicPosePreset

Bases: Enum

Presets for commonly used fly poses.

Attributes:

Name Type Description
NEUTRAL

The neutral (resting) pose of the fly.

Source code in src/flygym/compose/pose.py
class KinematicPosePreset(Enum):
    """Presets for commonly used fly poses.

    Attributes:
        NEUTRAL: The neutral (resting) pose of the fly.
    """

    NEUTRAL = "neutral"

    def get_dir(self) -> Path:
        match self:
            case KinematicPosePreset.NEUTRAL:
                return assets_dir / "model/pose/neutral/"
            case _:
                raise ValueError(f"Unsupported KinematicPosePreset: {self.value}")

    def get_pose_by_axis_order(
        self, axis_order: AxisOrder, mirror_left2right: bool = True
    ) -> KinematicPose:
        """Load the preset pose for a given axis order.

        Args:
            axis_order: The axis order to use.
            mirror_left2right: If True, mirror left-side angles to the right side.

        Returns:
            The loaded `KinematicPose`.
        """
        pose_dir = self.get_dir()
        pose_path = pose_dir / f"{axis_order.to_str()}.yaml"
        return KinematicPose(path=pose_path, mirror_left2right=mirror_left2right)

get_pose_by_axis_order(axis_order, mirror_left2right=True)

Load the preset pose for a given axis order.

Parameters:

Name Type Description Default
axis_order AxisOrder

The axis order to use.

required
mirror_left2right bool

If True, mirror left-side angles to the right side.

True

Returns:

Type Description
KinematicPose

The loaded KinematicPose.

Source code in src/flygym/compose/pose.py
def get_pose_by_axis_order(
    self, axis_order: AxisOrder, mirror_left2right: bool = True
) -> KinematicPose:
    """Load the preset pose for a given axis order.

    Args:
        axis_order: The axis order to use.
        mirror_left2right: If True, mirror left-side angles to the right side.

    Returns:
        The loaded `KinematicPose`.
    """
    pose_dir = self.get_dir()
    pose_path = pose_dir / f"{axis_order.to_str()}.yaml"
    return KinematicPose(path=pose_path, mirror_left2right=mirror_left2right)