Angles¶
Overview¶
Compute root angle measurements relative to gravity (vertical axis). Essential for gravitropism analysis and root growth direction studies.
Key functions:
- get_root_angle - Calculate root angle from proximal points
- get_vector_angles_from_gravity - Core angle calculation from vectors
- get_node_ind - Select points for angle computation
Angle Convention: 0° = straight down (with gravity), 90° = horizontal, 180° = straight up
Quick Example¶
import sleap_roots as sr
series = sr.Series.load("plant", primary_path="primary.slp")
pts = series.get_primary_points()
# Compute root angle
angles = sr.get_root_angle(pts, n_points=5)
print(f"Primary root angle: {angles[0, 0]:.1f}°")
API Reference¶
get_root_angle¶
get_root_angle ¶
get_root_angle(
pts: ndarray,
node_ind: ndarray,
proximal: bool = True,
base_ind: int = 0,
) -> ndarray
Find angles for each root.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pts
|
ndarray
|
Numpy array of points of shape (instances, nodes, 2). |
required |
node_ind
|
ndarray
|
Primary or lateral root node index. |
required |
proximal
|
bool
|
Boolean value, where true is proximal (default), false is distal. |
True
|
base_ind
|
int
|
Index of base node in the skeleton (default: 0). |
0
|
Returns:
| Type | Description |
|---|---|
ndarray
|
An array of shape (instances,) of angles in degrees, modulo 360. |
Source code in sleap_roots/angle.py
Example:
import sleap_roots as sr
import numpy as np
series = sr.Series.load("plant", primary_path="primary.slp")
pts = series.get_primary_points()
# Default: use first 5 points
angles = sr.get_root_angle(pts)
print(f"Angle (5 pts): {angles[0, 0]:.1f}°")
# Use more points for smoother estimate
angles_smooth = sr.get_root_angle(pts, n_points=10)
print(f"Angle (10 pts): {angles_smooth[0, 0]:.1f}°")
# Interpret results
angle = angles[0, 0]
if angle < 30:
print("Root growing downward (positive gravitropism)")
elif angle > 150:
print("Root growing upward (negative gravitropism)")
else:
print("Root growing at an angle")
See Also: DicotPipeline
get_vector_angles_from_gravity¶
get_vector_angles_from_gravity ¶
Calculate the angle of given vectors from the gravity vector.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
vectors
|
ndarray
|
An array of vectorss with shape (instances, 2), each representing a vector from start to end in an instance. |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
An array of angles in degrees with shape (instances,), representing the angle |
ndarray
|
between each vector and the downward-pointing gravity vector. |
Source code in sleap_roots/angle.py
get_node_ind¶
get_node_ind ¶
Find proximal/distal node index.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pts
|
ndarray
|
Numpy array of points of shape (instances, nodes, 2) or (nodes, 2). |
required |
proximal
|
bool
|
Boolean value, where true is proximal (default), false is distal. |
True
|
Returns:
| Type | Description |
|---|---|
ndarray
|
An array of shape (instances,) of proximal or distal node indices. |
ndarray
|
The proximal node is the first non-NaN node in the first half of the root. |
ndarray
|
The distal node is the last non-NaN node in the last half of the root. |
ndarray
|
If all nodes (or all nodes in the half of the root) are NaN, then zero is |
ndarray
|
returned. |
Source code in sleap_roots/angle.py
Example:
import sleap_roots as sr
pts = sr.Series.load("plant", primary_path="primary.slp").get_primary_points()
# Get indices for proximal 5 points
indices = sr.get_node_ind(pts, n_points=5)
print(f"Selected nodes: {indices[0, 0]}") # Array of node indices