funtracks.annotators
AnnotatorRegistry
AnnotatorRegistry(annotators: list[GraphAnnotator])
Bases: list[GraphAnnotator]
A list of annotators with coordinated operations.
Inherits from list[GraphAnnotator], so can be used directly as a list. Provides coordinated compute/update/enable/disable operations across all annotators.
Example
annotators = AnnotatorRegistry([ RegionpropsAnnotator(tracks, pos_key="centroid"), EdgeAnnotator(tracks), TrackAnnotator(tracks, tracklet_key="track_id"), ])
Can use as a list
annotators.append(MyCustomAnnotator(tracks))
Coordinated operations
annotators.activate_features(["area", "iou"]) annotators.compute()
Initialize with a list of annotators.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
annotators
|
list[GraphAnnotator]
|
List of instantiated annotator objects |
required |
all_features
all_features: dict[str, tuple[Feature, bool]]
Dynamically aggregate all_features from all annotators.
Returns:
| Type | Description |
|---|---|
dict[str, tuple[Feature, bool]]
|
Dictionary mapping feature keys to (Feature, is_enabled) tuples |
features
features: dict[str, Feature]
Get all currently active features from all annotators.
Returns:
| Type | Description |
|---|---|
dict[str, Feature]
|
Dictionary mapping feature keys to Feature definitions (only active features) |
activate_features
activate_features(keys: list[str]) -> None
Activate features across all annotators.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
keys
|
list[str]
|
List of feature keys to activate |
required |
Raises:
| Type | Description |
|---|---|
KeyError
|
If any feature keys are not available |
change_key
change_key(old_key: str, new_key: str) -> None
Rename a feature key across all annotators.
Finds the annotator that owns the feature and calls its change_key method. This allows the Tracks user to rename features without needing to find the specific annotator that manages it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
old_key
|
str
|
Existing key to rename. |
required |
new_key
|
str
|
New key to replace it with. |
required |
Raises:
| Type | Description |
|---|---|
KeyError
|
If old_key does not exist in any annotator. |
compute
compute(feature_keys: list[str] | None = None) -> None
Compute features across all annotators.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
feature_keys
|
list[str] | None
|
Optional list of specific feature keys to compute. If None, computes all currently active features. |
None
|
deactivate_features
deactivate_features(keys: list[str]) -> None
Deactivate features across all annotators.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
keys
|
list[str]
|
List of feature keys to deactivate |
required |
Raises:
| Type | Description |
|---|---|
KeyError
|
If any feature keys are not available |
update
update(action: BasicAction) -> None
Update features across all annotators based on the action.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
action
|
BasicAction
|
The action that triggered this update |
required |
EdgeAnnotator
EdgeAnnotator(tracks: Tracks)
Bases: GraphAnnotator
Manages edge features computed from segmentations or endpoint positions.
The possible features include: - Intersection over Union (IoU)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tracks
|
Tracks
|
The tracks to manage the edge features on |
required |
can_annotate
can_annotate(tracks) -> bool
Check if this annotator can annotate the given tracks.
Requires segmentation data to be present.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tracks
|
The tracks to check compatibility with |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if tracks have segmentation, False otherwise |
change_key
change_key(old_key: str, new_key: str) -> None
Rename a feature key in this annotator.
Overrides base implementation to also update the iou_key instance variable.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
old_key
|
str
|
Existing key to rename. |
required |
new_key
|
str
|
New key to replace it with. |
required |
Raises:
| Type | Description |
|---|---|
KeyError
|
If old_key does not exist. |
compute
compute(feature_keys: list[str] | None = None) -> None
Compute the currently included features and add them to the tracks.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
feature_keys
|
list[str] | None
|
Optional list of specific feature keys to compute. If None, computes all currently active features. Keys not in self.features (not enabled) are ignored. |
None
|
get_available_features
get_available_features(ndim: int = 3) -> dict[str, Feature]
Get all features that can be computed by this annotator.
Returns features with default keys. Custom keys can be specified at initialization time.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ndim
|
int
|
Total number of dimensions including time (unused for this annotator, kept for API consistency). Defaults to 3. |
3
|
Returns:
| Type | Description |
|---|---|
dict[str, Feature]
|
Dictionary mapping feature keys to Feature definitions. |
update
update(action: BasicAction)
Update the edge features based on the action.
Only responds to AddEdge and UpdateNodeSeg actions that affect edge IoU.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
action
|
BasicAction
|
The action that triggered this update |
required |
GraphAnnotator
GraphAnnotator(
tracks: Tracks, features: dict[str, Feature]
)
A base class for adding and updating graph features.
This class holds a set of features that it is responsible for. The annotator will compute these features and add them to the Tracks initially, and update them when necessary. The set of features will all be computed and updated together, although individual ones can be removed for efficiency.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tracks
|
Tracks
|
The tracks to manage features for. |
required |
features
|
dict[str, Feature]
|
A dict mapping keys to features that this annotator is capable of computing and updating. |
required |
Attributes:
| Name | Type | Description |
|---|---|---|
all_features |
dict[str, tuple[Feature, bool]]
|
Maps feature keys to (feature, is_included) tuples. Tracks both what can be computed and what is currently being computed. Defaults to computing nothing. |
features
features: dict[str, Feature]
The dict of features that this annotator currently manages.
Filtered from all_features based on inclusion flags.
activate_features
activate_features(keys: list[str]) -> None
Activate computation of the given features in the annotation process.
Filters the list to only features this annotator owns, ignoring others.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
keys
|
list[str]
|
List of feature keys to activate. Only keys in all_features are activated. |
required |
can_annotate
can_annotate(tracks: Tracks) -> bool
Check if this annotator can annotate the given tracks.
Subclasses should override this method to specify their requirements (e.g., segmentation, SolutionTracks, etc.).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tracks
|
Tracks
|
The tracks to check compatibility with |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if the annotator can annotate these tracks, False otherwise |
change_key
change_key(old_key: str, new_key: str) -> None
Rename a feature key in this annotator.
Base implementation updates the all_features dictionary. Subclasses should override this method to update any additional internal mappings they maintain.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
old_key
|
str
|
Existing key to rename. |
required |
new_key
|
str
|
New key to replace it with. |
required |
Raises:
| Type | Description |
|---|---|
KeyError
|
If old_key does not exist in all_features. |
compute
compute(feature_keys: list[str] | None = None) -> None
Compute a set of features and add them to the tracks.
This involves both updating the node/edge attributes on the tracks.graph
and adding the features to the FeatureDict, if necessary. This is distinct
from update to allow more efficient bulk computation of features.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
feature_keys
|
list[str] | None
|
Optional list of specific feature keys to compute. If None, computes all currently active features. Any provided keys not in the currently active set are ignored. |
None
|
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
If not implemented in subclass. |
deactivate_features
deactivate_features(keys: list[str]) -> None
Deactivate computation of the given features in the annotation process.
Filters the list to only features this annotator owns, ignoring others.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
keys
|
list[str]
|
List of feature keys to deactivate. Only keys in all_features are deactivated. |
required |
update
update(action: BasicAction) -> None
Update a set of features based on the given action.
This involves both updating the node or edge attributes on the tracks.graph
and adding the features to the FeatureDict, if necessary. This is distinct
from compute to allow more efficient computation of features for single
elements.
The action contains all necessary information about which elements to update (e.g., AddNode.node, AddEdge.edge, UpdateNodeSeg.node).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
action
|
BasicAction
|
The action that triggered this update |
required |
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
If not implemented in subclass. |
RegionpropsAnnotator
RegionpropsAnnotator(
tracks: Tracks, pos_key: str | None = DEFAULT_POS_KEY
)
Bases: GraphAnnotator
A graph annotator using regionprops to extract node features from segmentations.
The possible features include: - centroid (to use as node position) - area/volume - ellipsoid major/minor/semi-minor axes - circularity/sphericity - perimeter/surface area
Defaults to computing all features, but individual ones can be turned off by changing the self.include value at the corresponding index to the feature in self.features.
can_annotate
can_annotate(tracks) -> bool
Check if this annotator can annotate the given tracks.
Requires segmentation data to be present.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tracks
|
The tracks to check compatibility with |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if tracks have segmentation, False otherwise |
change_key
change_key(old_key: str, new_key: str) -> None
Rename a feature key in this annotator, and related mappings.
Overrides base implementation to also update the regionprops name mapping.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
old_key
|
str
|
Existing key to rename. |
required |
new_key
|
str
|
New key to replace it with. |
required |
Raises:
| Type | Description |
|---|---|
KeyError
|
If old_key does not exist. |
compute
compute(feature_keys: list[str] | None = None) -> None
Compute the currently included features and add them to the tracks.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
feature_keys
|
list[str] | None
|
Optional list of specific feature keys to compute. If None, computes all currently active features. Keys not in self.features (not enabled) are ignored. |
None
|
get_available_features
get_available_features(ndim: int = 3) -> dict[str, Feature]
Get all features that can be computed by this annotator.
Returns features with default keys. Custom keys can be specified at initialization time.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ndim
|
int
|
Total number of dimensions including time (3 or 4). Defaults to 3. |
3
|
Returns:
| Type | Description |
|---|---|
dict[str, Feature]
|
Dictionary mapping feature keys to Feature definitions. |
update
update(action: BasicAction)
Update the regionprops features based on the action.
Only responds to AddNode and UpdateNodeSeg actions that affect segmentation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
action
|
BasicAction
|
The action that triggered this update |
required |
TrackAnnotator
TrackAnnotator(
tracks: SolutionTracks,
tracklet_key: str | None = DEFAULT_TRACKLET_KEY,
lineage_key: str | None = DEFAULT_LINEAGE_KEY,
)
Bases: GraphAnnotator
A graph annotator to compute tracklet and lineage IDs for SolutionTracks only.
Currently, updating the tracklet and lineage IDs is left to Actions.
Attributes:
| Name | Type | Description |
|---|---|---|
tracklet_id_to_nodes |
dict[int, list[int]]
|
A mapping from tracklet ids to nodes in that tracklet |
lineage_id_to_nodes |
dict[int, list[int]]
|
A mapping from lineage ids to nodes in that lineage |
max_tracklet_id |
int
|
the maximum tracklet id used in the tracks |
max_lineage_id |
int
|
the maximum lineage id used in the tracks |
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tracks
|
SolutionTracks
|
The tracks to be annotated. Must be a solution. |
required |
tracklet_key
|
str | None
|
A key that already holds the tracklet ids on the graph. If provided, must be there for every node and already hold valid tracklet ids. Defaults to None. |
DEFAULT_TRACKLET_KEY
|
lineage_key
|
str | None
|
A key that already holds the lineage ids on the graph. If provided, must be there for every node and already hold valid lineage ids. Defaults to None. |
DEFAULT_LINEAGE_KEY
|
Raises:
| Type | Description |
|---|---|
ValueError
|
if the provided Tracks are not SolutionTracks (not a binary lineage tree) |
can_annotate
can_annotate(tracks) -> bool
Check if this annotator can annotate the given tracks.
Requires tracks to be a SolutionTracks instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tracks
|
The tracks to check compatibility with |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if tracks is a SolutionTracks instance, False otherwise |
change_key
change_key(old_key: str, new_key: str) -> None
Rename a feature key in this annotator.
Overrides base implementation to also update the tracklet_key and lineage_key instance variables.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
old_key
|
str
|
Existing key to rename. |
required |
new_key
|
str
|
New key to replace it with. |
required |
Raises:
| Type | Description |
|---|---|
KeyError
|
If old_key does not exist. |
compute
compute(feature_keys: list[str] | None = None) -> None
Compute the currently included features and add them to the tracks.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
feature_keys
|
list[str] | None
|
Optional list of specific feature keys to compute. If None, computes all currently active features. Keys not in self.features (not enabled) are ignored. |
None
|
get_available_features
get_available_features(ndim: int = 3) -> dict[str, Feature]
Get all features that can be computed by this annotator.
Returns features with default keys. Custom keys can be specified at initialization time.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ndim
|
int
|
Total number of dimensions including time (unused for this annotator, kept for API consistency). Defaults to 3. |
3
|
Returns:
| Type | Description |
|---|---|
dict[str, Feature]
|
Dictionary mapping feature keys to Feature definitions. |
update
update(action: BasicAction) -> None
Update track-level features based on the action.
Handles incremental updates for UpdateTrackIDs, AddNode, and DeleteNode actions. Other actions are ignored.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
action
|
BasicAction
|
The action that triggered this update. |
required |