Skip to content

funtracks.user_actions

UserAddEdge

UserAddEdge(
    tracks: SolutionTracks,
    edge: tuple[int, int],
    force: bool = False,
)

Bases: ActionGroup

Assumes that the endpoints already exist and have track ids.

Parameters:

Name Type Description Default
tracks SolutionTracks

the tracks to add the edge to

required
edge tuple[int, int]

The edge to add

required
force bool

Whether to force the action by removing any conflicting edges. Defaults to False.

False

UserAddNode

UserAddNode(
    tracks: SolutionTracks,
    node: int,
    attributes: dict[str, Any],
    pixels: tuple[ndarray, ...] | None = None,
    force: bool = False,
)

Bases: ActionGroup

Determines which basic actions to call when a user adds a node

  • Get the track id
  • Check if the track has divided earlier in time -> raise InvalidActionException
  • Check if there is an earlier and/or later node in the track
    • If there is earlier and later node, remove the edge between them
    • Add edges between the earlier/later nodes and the new node

Parameters:

Name Type Description Default
tracks SolutionTracks

the tracks to add the node to

required
node int

The node id of the new node to add

required
attributes dict[str, Any]

A dictionary from attribute strings to values. Must contain "time" and "track_id".

required
pixels tuple[ndarray, ...] | None

The pixels of the associated segmentation to add to the tracks. Defaults to None.

None
force bool

Whether to force the action by removing any conflicting edges. Defaults to False.

False

Raises:

Type Description
InvalidActionError

If the action cannot be completed because of one of

following reasons
- attributes dictionary does not contain `time` or `track_id`.
- a node with given ID already exists in the tracks.
- a node is trying to be added to a track that divided in a previous
time point (forceable).
- the parent track of the node will divide downstream of the current
time point (forceable).

UserSwapPredecessors

UserSwapPredecessors(
    tracks: SolutionTracks, nodes: tuple[int, int]
)

Bases: ActionGroup

Swap the predecessors (incoming edges) of two nodes.

The nodes do not need to be at the same time point, but both predecessors must be earlier in time than both nodes for the swap to be valid.

Parameters:

Name Type Description Default
tracks SolutionTracks

The tracks to perform the swap on.

required
nodes tuple[Node, Node]

A tuple with two nodes.

required

Raises:

Type Description
InvalidActionError

If not exactly two nodes are provided, if swapping would create invalid edges (predecessor not before node), if both nodes have the same predecessor, or if neither node has a predecessor.

UserUpdateSegmentation

UserUpdateSegmentation(
    tracks: SolutionTracks,
    new_value: int,
    updated_pixels: list[tuple[tuple[ndarray, ...], int]],
    current_track_id: int,
    force: bool = False,
)

Bases: ActionGroup

Assumes that the pixels have already been updated in the project.segmentation NOTE: Re discussion with Kasia: we should have a basic action that updates the segmentation, and that is the only place the segmentation is updated. The basic add_node action doesn't have anything with pixels.

Parameters:

Name Type Description Default
tracks SolutionTracks

The solution tracks that the user is updating.

required
new_value int

The new value that the user painted with

required
updated_pixels list[tuple[tuple[ndarray, ...], int]]

A list of node update actions, consisting of a numpy multi-index, pointing to the array elements that were changed (a tuple with len ndims), and the value before the change

required
current_track_id int

The track id to use if adding a new node, usually the currently selected track id in the viewer.

required
force bool

Whether to force the operation by removing conflicting edges. Defaults to False.

False