Skip to content

Tips

Overview

Detect and extract root tip coordinates. Used for tracking root growth direction and computing tip-based traits.

Key functions: - get_tips - Extract tip points from root arrays - get_tip_xs - Get x-coordinates of tips - get_tip_ys - Get y-coordinates of tips

Quick Example

import sleap_roots as sr

series = sr.Series.load("plant", lateral_path="lateral.slp")
lateral_pts_list = series.get_lateral_points()

# Get tip points
tips = sr.get_tips(lateral_pts_list)
print(f"Tip shape: {tips.shape}")  # (n_laterals, 2)
print(f"First tip: x={tips[0, 0]:.1f}, y={tips[0, 1]:.1f}")

API Reference

get_tips

get_tips

get_tips(pts: ndarray) -> ndarray

Return tips (last node) from each root.

Parameters:

Name Type Description Default
pts ndarray

Root landmarks as array of shape (instances, nodes, 2) or (nodes, 2).

required

Returns:

Type Description
ndarray

Array of tips. If the input is (nodes, 2), an array of shape (2,) will be

ndarray

returned. If the input is (instances, nodes, 2), an array of shape

ndarray

(instances, 2) will be returned. If there is no root, or the roots don't have

ndarray

tips, an array of shape (instances, 2) of NaNs will be returned.

Source code in sleap_roots/tips.py
def get_tips(pts: np.ndarray) -> np.ndarray:
    """Return tips (last node) from each root.

    Args:
        pts: Root landmarks as array of shape `(instances, nodes, 2)` or `(nodes, 2)`.

    Returns:
        Array of tips. If the input is `(nodes, 2)`, an array of shape `(2,)` will be
        returned. If the input is `(instances, nodes, 2)`, an array of shape
        `(instances, 2)` will be returned. If there is no root, or the roots don't have
        tips, an array of shape `(instances, 2)` of NaNs will be returned.
    """
    # If the input has shape `(nodes, 2)`, reshape it for consistency
    if pts.ndim == 2:
        pts = pts[np.newaxis, ...]

    # Get the last point of each instance
    tip_pts = pts[:, -1, :]  # Shape is `(instances, 2)`

    # If the shape is `(1, 2)` return pts with shape `(2,)` instead
    if tip_pts.shape[0] == 1:
        return tip_pts[0]

    return tip_pts

Example:

import sleap_roots as sr
import numpy as np

series = sr.Series.load("plant", lateral_path="lateral.slp")
lateral_pts_list = series.get_lateral_points()

# Extract all lateral tips
tips = sr.get_tips(lateral_pts_list)

# Handle NaN (missing tips)
valid_tips = tips[~np.isnan(tips).any(axis=1)]
print(f"Valid tips: {len(valid_tips)}/{len(tips)}")


get_tip_xs

get_tip_xs

get_tip_xs(tip_pts: ndarray) -> ndarray | floating

Get x coordinates of tip points.

Parameters:

Name Type Description Default
tip_pts ndarray

Root tip points as array of shape (instances, 2) or (2,) when there is only one tip.

required
Return

An array of tip x-coordinates (instances,) or a scalar when there is only one root.

Source code in sleap_roots/tips.py
def get_tip_xs(tip_pts: np.ndarray) -> np.ndarray | np.floating:
    """Get x coordinates of tip points.

    Args:
        tip_pts: Root tip points as array of shape `(instances, 2)` or `(2,)` when there
            is only one tip.

    Return:
        An array of tip x-coordinates (instances,) or a scalar when there is only one root.
    """
    # Check for the 2D shape of the input array
    if tip_pts.ndim == 1:
        # If shape is `(2,)`, then reshape it to `(1, 2)` for consistency
        tip_pts = tip_pts.reshape(1, 2)
    elif tip_pts.ndim != 2:
        raise ValueError("Input array must be of shape `(instances, 2)` or `(2, )`.")

    # At this point, `tip_pts` should be of shape `(instances, 2)`.
    # Get the tip x-value
    tip_xs = tip_pts[:, 0]

    # Now it has shape `(instances,)`
    if tip_xs.shape == (1,):
        # Return a scalar
        return tip_xs[0]

    return tip_xs

get_tip_ys

get_tip_ys

get_tip_ys(tip_pts: ndarray) -> ndarray | floating

Get y coordinates of tip points.

Parameters:

Name Type Description Default
tip_pts ndarray

Root tip points as array of shape (instances, 2) or (2,) when there is only one tip.

required
Return

An array of tip y-coordinates (instances,) or a scalar when there is only one root.

Source code in sleap_roots/tips.py
def get_tip_ys(tip_pts: np.ndarray) -> np.ndarray | np.floating:
    """Get y coordinates of tip points.

    Args:
        tip_pts: Root tip points as array of shape `(instances, 2)` or `(2,)` when there
            is only one tip.

    Return:
        An array of tip y-coordinates (instances,) or a scalar when there is only one root.
    """
    # Check for the 2D shape of the input array
    if tip_pts.ndim == 1:
        # If shape is `(2,)`, then reshape it to `(1, 2)` for consistency
        tip_pts = tip_pts.reshape(1, 2)
    elif tip_pts.ndim != 2:
        raise ValueError("Input array must be of shape `(instances, 2)` or `(2, )`.")

    # At this point, `tip_pts` should be of shape `(instances, 2)`.
    # Get the tip y-value
    tip_ys = tip_pts[:, 1]
    # Now it has shape `(instances,)`
    if tip_ys.shape == (1,):
        # Return a scalar
        return tip_ys[0]

    return tip_ys

Example:

import sleap_roots as sr

lateral_pts_list = sr.Series.load("plant", lateral_path="lateral.slp").get_lateral_points()

# Get tip coordinates separately
tip_xs = sr.get_tip_xs(lateral_pts_list)
tip_ys = sr.get_tip_ys(lateral_pts_list)

print(f"Tip x-coordinates: {tip_xs}")
print(f"Tip y-coordinates: {tip_ys}")


  • Bases - Base point detection (opposite end of root)
  • Lengths - Tip-to-base distances

See Also