napari_track_edit.data_views.views.layers.track_labels

Classes

TrackLabels

Extended labels layer that holds the track information and emits

Functions

updates_from_masked_atoms(...)

Turn napari >= 0.8 paint atoms into one segmentation update per label.

updates_from_index_atoms(...)

Turn napari ≤ 0.7 paint atoms into one segmentation update per label.

new_label(layer)

A function to override the default napari labels new_label function.

_new_label(layer[, new_track_id])

A function to get a new label for a given TrackLabels layer. This helper is

Module Contents

napari_track_edit.data_views.views.layers.track_labels.updates_from_masked_atoms(atoms) → list[tuple[tracksdata.nodes.Mask, int, int]]

Turn napari >= 0.8 paint atoms into one segmentation update per label.

Each atom is a _MaskedPaintAtom: a bounding box, a mask of the pixels that changed inside it, their values before the change, and the value painted.

Note: A stroke emits one atom per brush position, normally napari records a pixel only the first time it is painted: it drops pixels that already hold the value being painted. That check reads the layer’s data, which we never write back (see ContourLabels._paint_region_with_mask), so every brush position reports its whole

box afresh, and a slow drag repeats the same box dozens of times. Atoms that share a box are therefore mergedfirst, so that a pixel is turned into mask pixels only once.

Parameters:

atoms – the atoms of one paint event, all in the mask form.

Returns:

one (mask, time, old value) per label painted

over, per brush position and time point. Each mask carries the bounding box of the brush position it came from; funtracks tightens them around their own pixels and combines the ones of a label.

Return type:

list[tuple[Mask, int, int]]

napari_track_edit.data_views.views.layers.track_labels.updates_from_index_atoms(atoms) → list[tuple[tuple[numpy.ndarray, ...], int]]

Turn napari ≤ 0.7 paint atoms into one segmentation update per label.

Each atom is a data_setitem 3-tuple: a multi-index of the elements that changed, their values before the change, and the value after it. There is no bounding box to work from, so the coordinates are handed to funtracks, which builds the masks.

Parameters:

atoms – the atoms of one paint event, all in the multi-index form.

Returns:

one (multi-index, old value) per

label painted over, per time point. A coordinate may appear twice in an index, which funtracks is free to ignore: painting a pixel into a mask is idempotent.

Return type:

list[tuple[tuple[np.ndarray, …], int]]

napari_track_edit.data_views.views.layers.track_labels.new_label(layer: TrackLabels)

A function to override the default napari labels new_label function. Must be registered (see end of this file)

napari_track_edit.data_views.views.layers.track_labels._new_label(layer: TrackLabels, new_track_id=True)

A function to get a new label for a given TrackLabels layer. This helper is abstracted out because we want to do the same thing both with and without making a new track id for the layer.

Parameters:
  • layer (TrackLabels) – A TrackLabels layer from which get a new label for drawing a new segmentation. Updates the selected_label attribute.

  • new_track_id (bool, optional) – If you should also generate a new track id and set it to the selected_track attribute. Defaults to True.

class napari_track_edit.data_views.views.layers.track_labels.TrackLabels(viewer: napari.Viewer, data: numpy.array, name: str, opacity: float, scale: tuple, tracks_viewer: napari_track_edit.data_views.views_coordinator.tracks_viewer.TracksViewer)

Bases: napari_track_edit.data_views.views.layers.contour_labels.ContourLabels

Extended labels layer that holds the track information and emits and responds to dynamics visualization signals

property _type_string: str
tracks_viewer
track_colormap
viewer
highlight_opacity = 1
foreground_opacity = 0.6
background_opacity = 0.3
highlight_contour = False
foreground_contour = False
click(_, event)
new_label() → None

Select a valid new label to paint a new track with.

Called by TracksViewer.request_new_track, which owns the “start a new track” action for all views. The label is new by construction, guard can be skipped.

process_click(event: napari.utils.events.Event, value: int | None = None, side_button: int | None = None, layer: napari_track_edit.data_views.views.layers.contour_labels.ContourLabels | None = None)

Process the click event to update the selected nodes.

Parameters:
  • event (Event) – The click event.

  • value (int) – The label value (node) at the clicked position.

  • side_button (int | None) – the integer for the mouse side buttons (4: back, 5: forward)

  • layer (ContourLabels | None) – The (ortho view) layer from which the click originated. If provided, it is used to check label visibility in that layer’s colormap.

_check_mode()

Check if the mode is valid and call the ensure_valid_label function

redo()

Overwrite the redo functionality of the labels layer and invoke redo action on the tracks_viewer.tracks first

undo()

Overwrite undo function and invoke undo action on the tracks_viewer.tracks first

static _parse_paint_event(event_val)

Turn a paint event into the segmentation updates funtracks expects.

napari reports the atoms of an event in one of two forms, never mixed within an event: the mask form of napari >= 0.8, and the multi-index form that data_setitem still uses.

Parameters:

event_val (list[tuple]) – the paint “atoms” the labels layer recorded for this event.

Returns:

the updates for every label painted over, in whichever of

the two forms UserUpdateSegmentation was handed. Empty when the event changed nothing.

Return type:

list[tuple]

_revert_paint(_, source_layer: napari.layers.Labels | None = None)

Revert a paint event after it fails validation (no actions have been created). This keeps the view synced with the backend data. been created). If a source_layer is provided, the paint event will be reverted on this layer (this is necessary for orthoviews). This keeps the view synced with the backend data.

_on_paint(event)

Listen to the paint event and check which track_ids have changed

_refresh()

Refresh the data in the labels layer

update_label_colormap(visible: list[int] | str) → None

Updates the opacity for the highlighted, foreground, and background labels, and adds labels to the filled_labels if necessary.

new_colormap()

Override existing function to generate new colormap on tracks_viewer and emit refresh signal to update colors in all layers/widgets

update_selected_label()

Update the selected label in the labels layer

_ensure_valid_label(event: napari.utils.events.Event | None = None)

Make sure a valid label is selected, because it is not allowed to paint with a label that already exists at a different timepoint.

Scenarios:

  1. If a node with the selected label value (node id) exists at a different time point, check if there is any node with the same track_id at the current time point.

    1. If there is a node with the same track id, select that one, so that it can be used to update an existing node.

    2. If there is no node with the same track id, create a new node id and paint with the track_id of the selected label. This can be used to add a new node with the same track id at a time point where it does not (yet) exist (anymore).

  2. If there is no existing node with this value in the graph, it is assumed that you want to add a node with the current track id. Retrieve the track_id from self.current_track_id and use it to find if there are any nodes of this track id at current time point.

  3. If no node with this label exists yet, it is valid and can be used to start a new track id. Therefore, create a new node id and map a new color. Add it to the dictionary.

  4. If a node with the label exists at the current time point, it is valid and can be used to update the existing node in a paint event. No action is needed.