Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v1.1 cleanup #73

Merged
merged 3 commits into from
Sep 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions docs/source/getting_started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ It contains the following:
If your input was a Points layer, the ``node_id`` is simply the index of the
node in the list of points.
- Note: This does not save the output segmentation. If you want to save
the relabeled segmentation, you can do so through napari by selecting the
layer and then selecting ``File``-> ``Save selected layers``
the relabeled segmentation, you can do so through napari by selecting the
layer and then selecting ``File``-> ``Save selected layers``
- The ``Back to editing`` button, which will return you to the ``Run Editor`` in its
previous state.
- The ``Edit this run`` button. This button will take you back to the ``Run Editor``,
Expand All @@ -126,11 +126,7 @@ previous sessions do not appear here until you load them from disk with the

The tracking results can also be visualized as a lineage tree.
You can open the lineage tree widget via ``Plugins`` > ``Motile`` > ``Lineage View``.
For more details, go to `this docs page`_.
For more details, go to the :doc:`Tree View <tree_view>` documentation.



.. _here: docs/source/key_bindings.rst
.. _this docs page: docs/source/tree_view.rst
.. _Issue #48: https://github.com/funkelab/motile_napari_plugin/issues/48
.. _Cell Tracking Challenge: https://celltrackingchallenge.net/
10 changes: 4 additions & 6 deletions src/motile_plugin/layers/track_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,7 @@ def __init__(
name: str,
colormap: CyclicLabelColormap,
):
if tracks is None or tracks.graph is None:
graph = nx.DiGraph()
else:
graph = tracks.graph

graph = nx.DiGraph() if tracks.graph is None else tracks.graph
track_data, track_props, track_edges = to_napari_tracks_layer(
graph, frame_key=tracks.time_attr, location_key=tracks.pos_attr
)
Expand All @@ -40,6 +36,7 @@ def __init__(

self.viewer = viewer
self.colormaps_dict["track_id"] = colormap
self.colormap = "turbo" # just to refresh the colormap

self.tracks_layer_graph = copy.deepcopy(self.graph) # for restoring graph later

Expand All @@ -63,6 +60,7 @@ def update_track_visibility(self, visible: list[int] | str) -> None:
self.track_colors[:, 3] = 0
self.track_colors[track_id_mask, 3] = 1
if len(self.graph.items()) == 0:
self.display_graph = False # empty dicts to not trigger update (bug?) so disable the graph entirely as a workaround
self.display_graph = False # empty dicts to not trigger update (bug?)
# so disable the graph entirely as a workaround
else:
self.display_graph = True
2 changes: 1 addition & 1 deletion src/motile_plugin/utils/relabel_segmentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def relabel_segmentation(
previous_seg_id = solution_nx_graph.nodes[node][NodeAttr.SEG_ID.value]
assert previous_seg_id != 0
tracklet_id = solution_nx_graph.nodes[node]["tracklet_id"]
hypothesis_id = solution_nx_graph.nodes[node].get([NodeAttr.SEG_HYPO.value], 0)
hypothesis_id = solution_nx_graph.nodes[node].get(NodeAttr.SEG_HYPO.value, 0)
previous_seg_mask = segmentation[time_frame, hypothesis_id] == previous_seg_id
tracked_masks[time_frame, 0][previous_seg_mask] = tracklet_id
return tracked_masks
39 changes: 17 additions & 22 deletions src/motile_plugin/widgets/tracks_view/tree_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,7 @@ def mouseDragEvent(self, ev, axis=None):
# Otherwise, disable rectangular zoom mode
self.setMouseMode(self.PanMode)

if (
axis is not None
and ev.button() == QtCore.Qt.MouseButton.RightButton
):
if axis is not None and ev.button() == QtCore.Qt.MouseButton.RightButton:
ev.ignore()
else:
pg.ViewBox.mouseDragEvent(self, ev, axis=axis)
Expand Down Expand Up @@ -99,8 +96,8 @@ def update(
feature (str): The feature to be plotted ('tree' or 'area')
selected_nodes (list[Any]): The currently selected nodes to be highlighted
"""
self.set_data(track_df, feature)
self.set_view(view_direction, feature)
self.set_data(track_df, feature)
self._update_viewed_data() # this can be expensive
self.set_selection(selected_nodes, feature)

Expand All @@ -112,7 +109,7 @@ def set_view(self, view_direction: str, feature: str):

Args:
view_direction (str): "horizontal" or "vertical"
feature (str): the feature being displayed, it can be either 'tree' or 'area'
feature (str): the feature being displayed, it can be 'tree' or 'area'
"""

if view_direction == self.view_direction and feature == self.feature:
Expand All @@ -127,7 +124,7 @@ def set_view(self, view_direction: str, feature: str):
self.setLabel("bottom", text="")
else:
self.getAxis("bottom").setStyle(showValues=True)
self.setLabel("bottom", text="Number of pixels")
self.setLabel("bottom", text="Area in Scaled Pixels")
self.invertY(True) # to show tracks from top to bottom
elif view_direction == "horizontal":
self.setLabel("bottom", text="Time Point")
Expand All @@ -136,7 +133,7 @@ def set_view(self, view_direction: str, feature: str):
self.setLabel("left", text="")
self.getAxis("left").setStyle(showValues=False)
else:
self.setLabel("left", text="Number of pixels")
self.setLabel("left", text="Area in Scaled Pixels")
self.getAxis("left").setStyle(showValues=True)
self.invertY(False)

Expand Down Expand Up @@ -167,9 +164,9 @@ def set_data(self, track_df: pd.DataFrame, feature: str) -> None:
self._create_pyqtgraph_content(track_df, feature)

def _update_viewed_data(self):
self.g.scatter.setPen(
pg.mkPen(QColor(150, 150, 150))
) # first reset the pen to avoid problems with length mismatch between the different properties
# first reset the pen to avoid problems with length mismatch between the
# different properties
self.g.scatter.setPen(pg.mkPen(QColor(150, 150, 150)))
self.g.scatter.setSize(10)
if len(self._pos) == 0 or self.view_direction == "vertical":
pos_data = self._pos
Expand All @@ -188,9 +185,7 @@ def _update_viewed_data(self):
self.g.scatter.setSize(self.sizes)
self.autoRange()

def _create_pyqtgraph_content(
self, track_df: pd.DataFrame, feature: str
) -> None:
def _create_pyqtgraph_content(self, track_df: pd.DataFrame, feature: str) -> None:
"""Parse the given track_df into the format that pyqtgraph expects
and save the information as attributes.

Expand Down Expand Up @@ -320,9 +315,7 @@ class TreeWidget(QWidget):
def __init__(self, viewer: napari.Viewer):
super().__init__()
self.track_df = pd.DataFrame() # all tracks
self.lineage_df = (
pd.DataFrame()
) # the currently viewed subset of lineages
self.lineage_df = pd.DataFrame() # the currently viewed subset of lineages
self.graph = None
self.mode = "all" # options: "all", "lineage"
self.feature = "tree" # options: "tree", "area"
Expand Down Expand Up @@ -436,8 +429,11 @@ def _update_track_data(self) -> None:
)
self.graph = self.tracks_viewer.tracks.graph

# check whether we have area measurements and therefore should activate the area button
# check whether we have area measurements and therefore should activate the area
# button
if "area" not in self.track_df.columns:
if self.feature_widget.feature == "area":
self.feature_widget._toggle_feature_mode()
self.feature_widget.show_area_radio.setEnabled(False)
else:
self.feature_widget.show_area_radio.setEnabled(True)
Expand Down Expand Up @@ -483,15 +479,14 @@ def _set_mode(self, mode: str) -> None:
)

def _set_feature(self, feature: str) -> None:
"""Set the feature mode to 'tree' or 'area'. For this the view is always horizontal.
"""Set the feature mode to 'tree' or 'area'. For this the view is always
horizontal.

Args:
feature (str): The feature to plot. Options are "tree" or "area"
"""
if feature not in ["tree", "area"]:
raise ValueError(
f"Feature must be 'tree' or 'area', got {feature}"
)
raise ValueError(f"Feature must be 'tree' or 'area', got {feature}")

self.feature = feature
if feature == "tree" and self.mode == "all":
Expand Down
Loading