Skip to content

Commit

Permalink
add editing sctc by interval
Browse files Browse the repository at this point in the history
  • Loading branch information
dummyindex committed Sep 19, 2023
1 parent 7b52ef7 commit 86733a2
Show file tree
Hide file tree
Showing 2 changed files with 167 additions and 3 deletions.
100 changes: 97 additions & 3 deletions livecellx/core/sct_operator.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ def __init__(
img_dataset=None,
time_span=(0, None),
meta=None,
uns=None,
):
self.select_info = [] # [cur_sct, cur_sc, selected_shape_index]
self.operator = operator
Expand All @@ -60,6 +61,11 @@ def __init__(
else:
self.meta = meta

if uns is None:
self.uns = {}
else:
self.uns = uns

def remove_sc_operator(self, sc_operator):
self.sc_operators.remove(sc_operator)

Expand Down Expand Up @@ -348,9 +354,19 @@ def setup_from_sctc(self, sctc: SingleCellTrajectoryCollection, contour_sample_n
self.traj_collection = sctc
return shape_layer

def setup_by_timespan(self, span: tuple, contour_sample_num=20):
tmp_sctc = filter_sctc_by_time_span(self.traj_collection, span)
if self.shape_layer is not None:
self.remove_shape_layer()
shape_layer = NapariVisualizer.gen_trajectories_shapes(
tmp_sctc, self.viewer, contour_sample_num=contour_sample_num
)
self.setup_shape_layer(shape_layer)
return shape_layer

def store_shape_layer_info(self, update_slice=None):
"""
Stores the original face colors, properties, single cells, and shape data of the shape layer.
Stores the original face colors, properties, single cells, and shape data of the shape layer. Note that the single cell objects are copied as reference.
Args:
update_slice: A slice object representing the range of indices to update. If None, all indices are updated.
Expand Down Expand Up @@ -864,6 +880,9 @@ def create_scs_edit_viewer_by_interval(
clear_prev_batch=True,
contour_sample_num=30,
):
"""
Creates a viewer and an sct_operator for editing SingleCellStatic objects.
"""
# TODO: a potential bug is that the slice index is not the same concept as the time. A solution is to add time frame to shape properties
# Here for now we assume indices represents timeframes
sct_operator = create_scs_edit_viewer(
Expand Down Expand Up @@ -920,8 +939,8 @@ def _move_span(viewer, offset):
if clear_prev_batch:
# TODO: shapes may be invisible, though select is sc/sct based and should be fine
sct_operator.clear_selection()
temp_sc_trajs = create_sctc_from_scs(single_cells)
temp_sc_trajs = filter_sctc_by_time_span(temp_sc_trajs, cur_span)
all_sc_trajs = create_sctc_from_scs(single_cells)
temp_sc_trajs = filter_sctc_by_time_span(all_sc_trajs, cur_span)
if len(temp_sc_trajs) != 0:
sct_operator.setup_from_sctc(temp_sc_trajs, contour_sample_num=contour_sample_num)
else:
Expand Down Expand Up @@ -950,3 +969,78 @@ def load_from_cur_step(viewer):
_move_span(viewer, cur_step - cur_idx)

return viewer


def create_sctc_edit_viewer_by_interval(
sctc: SingleCellTrajectoryCollection,
img_dataset: LiveCellImageDataset,
span_interval=10,
viewer=None,
clear_prev_batch=True,
contour_sample_num=30,
uns_cur_idx_key="_lcx_sctc_cur_idx",
):
"""
Creates a viewer and an sct_operator for editing SingleCellStatic objects.
"""
# TODO: a potential bug is that the slice index is not the same concept as the time. A solution is to add time frame to shape properties
# Here for now we assume indices represents timeframes
sct_operator = create_scts_operator_viewer(
sctc,
img_dataset=img_dataset,
viewer=viewer,
contour_sample_num=contour_sample_num,
)

viewer = sct_operator.viewer
max_time = max(img_dataset.times)
cur_index = 0

sct_operator.uns[uns_cur_idx_key] = cur_index

def _get_cur_idx(sct_operator):
cur_idx = sct_operator.uns[uns_cur_idx_key]
return cur_idx

def _move_span(viewer, offset):
try:
cur_idx = _get_cur_idx(sct_operator)
cur_idx += offset
cur_idx = min(cur_idx, max_time) # (max_time - span_interval) is acceptable as well here
cur_idx = max(cur_idx, 0)
cur_span = (cur_idx, cur_idx + span_interval)
sct_operator.uns[uns_cur_idx_key] = cur_idx
# if clear_prev_batch:
# sct_operator.close()
# sct_operator = create_scs_edit_viewer(single_cells, img_dataset = dic_dataset, viewer = viewer, time_span=cur_span)
if clear_prev_batch:
# TODO: shapes may be invisible, though select is sc/sct based and should be fine
sct_operator.clear_selection()
sct_operator.setup_by_timespan(cur_span, contour_sample_num=contour_sample_num)
viewer.dims.set_point(0, cur_idx)
except Exception as e:
print("Error:", e)
print("Failed to load next span. Please try again.")
import traceback

traceback.print_exc()

@viewer.bind_key("n")
def next_span(viewer):
print(">>> debug: next_span")
_move_span(viewer, span_interval + 1)

@viewer.bind_key("b")
def prev_span(viewer):
print(">>> debug: prev_span")
_move_span(viewer, -span_interval - 1)

@viewer.bind_key("m")
def load_from_cur_step(viewer):
print(">>> debug: cur_idx span")
cur_step = viewer.dims.point[0]
cur_idx = _get_cur_idx(sct_operator)
_move_span(viewer, cur_step - cur_idx)

load_from_cur_step(viewer)
return sct_operator
70 changes: 70 additions & 0 deletions notebooks/tutorial_create_sct_operator_interval.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from livecellx.sample_data import tutorial_three_image_sys\n",
"from livecellx.core.io_sc import prep_scs_from_mask_dataset\n",
"\n",
"dic_dataset, mask_dataset = tutorial_three_image_sys()\n",
"single_cells = prep_scs_from_mask_dataset(mask_dataset, dic_dataset)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from typing import List\n",
"from livecellx.track.sort_tracker_utils import (\n",
" gen_SORT_detections_input_from_contours,\n",
" update_traj_collection_by_SORT_tracker_detection,\n",
" track_SORT_bbox_from_contours,\n",
" track_SORT_bbox_from_scs\n",
")\n",
"\n",
"\n",
"traj_collection = track_SORT_bbox_from_scs(single_cells, dic_dataset, mask_dataset=mask_dataset, max_age=0, min_hits=1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from livecellx.core.sct_operator import create_scs_edit_viewer, SctOperator, create_scs_edit_viewer_by_interval, _get_viewer_sct_operator, create_sctc_edit_viewer_by_interval\n",
"import livecellx\n",
"import importlib\n",
"importlib.reload(livecellx.core.sct_operator)\n",
"\n",
"sct_opeartor = livecellx.core.sct_operator.create_sctc_edit_viewer_by_interval(traj_collection, img_dataset=dic_dataset, span_interval=0)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "livecell-work",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.16"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

0 comments on commit 86733a2

Please sign in to comment.