Skip to content

Commit

Permalink
Merge branch 'public-main'
Browse files Browse the repository at this point in the history
  • Loading branch information
JoOkuma committed May 16, 2024
2 parents 1179c72 + 4c517a2 commit 3d92c21
Show file tree
Hide file tree
Showing 34 changed files with 272 additions and 206 deletions.
4 changes: 2 additions & 2 deletions docs/source/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ Basic Usage
from ultrack import MainConfig, track, to_tracks_layer
# Load your data
detection = ...
foreground = ...
boundaries = ...
# Create a config
config = MainConfig()
# Run the tracking
track(
detection=detection,
foreground=foreground,
edges=boundaries,
config=config,
)
Expand Down
12 changes: 6 additions & 6 deletions ultrack/api/_test/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,17 @@
from ultrack.api.utils.zarr import get_channels_from_ome_zarr
from ultrack.core.database import clear_all_data
from ultrack.imgproc import detect_foreground, robust_invert
from ultrack.utils import labels_to_edges
from ultrack.utils import labels_to_contours
from ultrack.utils.array import array_apply
from ultrack.utils.cuda import on_gpu


def _get_ultrack_solution(
config: MainConfig, detection: np.ndarray, edges: np.ndarray
config: MainConfig, foreground: np.ndarray, edges: np.ndarray
) -> Tuple[pd.DataFrame, Dict, zarr.Array]:
clear_all_data(settings.ultrack_data_config.database_path)

segment(detection=detection, edge=edges, config=config)
segment(foreground=foreground, contours=edges, config=config)
link(config)
solve(config)

Expand Down Expand Up @@ -269,10 +269,10 @@ def test_from_labels(experiment_instance: Experiment, label_to_edges_kwargs: dic
assert experiment.status != ExperimentStatus.ERROR

# compare the results with the ones obtained from the ultrack module
detection, edges = labels_to_edges(
detection, edges = labels_to_contours(
label_data,
detection_store_or_path=zarr.MemoryStore(),
edges_store_or_path=zarr.MemoryStore(),
foreground_store_or_path=zarr.MemoryStore(),
contours_store_or_path=zarr.MemoryStore(),
**label_to_edges_kwargs,
)

Expand Down
12 changes: 6 additions & 6 deletions ultrack/api/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
from ultrack.config import MainConfig
from ultrack.core.export import tracks_layer_to_networkx, tracks_layer_to_trackmate
from ultrack.imgproc import detect_foreground, robust_invert
from ultrack.utils import labels_to_edges
from ultrack.utils import labels_to_contours
from ultrack.utils.array import array_apply, create_zarr
from ultrack.utils.cuda import on_gpu

Expand Down Expand Up @@ -514,10 +514,10 @@ async def auto_from_labels(websocket: WebSocket) -> None:
detection_path = str(Path(temp_path) / "detection.zarr")
edges_path = str(Path(temp_path) / "edges.zarr")

labels_to_edges(
labels_to_contours(
label_data,
detection_store_or_path=detection_path,
edges_store_or_path=edges_path,
foreground_store_or_path=detection_path,
contours_store_or_path=edges_path,
**label_to_edges_kwargs,
)

Expand Down Expand Up @@ -564,8 +564,8 @@ async def segment_link_and_solve(experiment: Experiment, ws: WebSocket) -> None:
experiment.status = ExperimentStatus.SEGMENTING
update_experiment(experiment)
segment(
detection=detection,
edge=edges,
foreground=detection,
contours=edges,
config=config,
)
except Exception as e:
Expand Down
14 changes: 7 additions & 7 deletions ultrack/cli/_test/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ def test_segment(
"segment",
"-cfg",
instance_config_path,
"-dl",
"detection",
"-el",
"edges",
"-fl",
"foreground",
"-cl",
"contours",
]
+ zarr_dataset_paths
)
Expand All @@ -76,7 +76,7 @@ def test_link_iou(self, instance_config_path: str) -> None:
def test_link_with_images(
self, instance_config_path: str, zarr_dataset_paths: List[str]
) -> None:
# using detection and edges layer to simulate image channel
# using foreground and contours layer to simulate image channel
_run_command(
["link", "-cfg", str(instance_config_path), "-ow"] + zarr_dataset_paths[:2]
)
Expand Down Expand Up @@ -170,9 +170,9 @@ def test_estimate_params(zarr_dataset_paths: List[str], tmp_path: Path) -> None:
_run_command(["estimate_params", zarr_dataset_paths[2], "-o", str(tmp_path)])


def test_labels_to_edges(zarr_dataset_paths: List[str], tmp_path: Path) -> None:
def test_labels_to_contours(zarr_dataset_paths: List[str], tmp_path: Path) -> None:
_run_command(
["labels_to_edges", zarr_dataset_paths[2], "-o", str(tmp_path / "output")]
["labels_to_contours", zarr_dataset_paths[2], "-o", str(tmp_path / "output")]
)


Expand Down
26 changes: 13 additions & 13 deletions ultrack/cli/labels_to_edges.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,37 +12,37 @@
paths_argument,
)
from ultrack.utils.data import validate_and_overwrite_path
from ultrack.utils.edge import labels_to_edges
from ultrack.utils.edge import labels_to_contours


@click.command("labels_to_edges")
@click.command("labels_to_contours")
@paths_argument()
@output_directory_option(help="`detection.zarr` and `edges.zarr` output directory.")
@output_directory_option(help="`detection.zarr` and `contours.zarr` output directory.")
@napari_reader_option()
@click.option(
"--sigma",
"-s",
type=float,
default=None,
show_default=True,
help="Edge smoothing parameter (gaussian blur sigma). No blurring by default.",
help="Contour smoothing parameter (gaussian blur sigma). No blurring by default.",
)
@overwrite_option()
def labels_to_edges_cli(
def labels_to_contours_cli(
paths: Sequence[Path],
output_directory: Path,
reader_plugin: str,
sigma: Optional[float],
overwrite: bool,
) -> None:
"""
Converts and merges a sequence of labels into ultrack input format (detection and edges)
Converts and merges a sequence of labels into ultrack input format (foreground and contours)
"""
detection_path = output_directory / "detection.zarr"
validate_and_overwrite_path(detection_path, overwrite, "cli")
foreground_path = output_directory / "foreground.zarr"
validate_and_overwrite_path(foreground_path, overwrite, "cli")

edges_path = output_directory / "edges.zarr"
validate_and_overwrite_path(edges_path, overwrite, "cli")
contours_path = output_directory / "contours.zarr"
validate_and_overwrite_path(contours_path, overwrite, "cli")

_initialize_plugins()

Expand All @@ -52,9 +52,9 @@ def labels_to_edges_cli(
labels = [layer.data for layer in viewer.layers]
del viewer

labels_to_edges(
labels_to_contours(
labels,
sigma=sigma,
detection_store_or_path=detection_path,
edges_store_or_path=edges_path,
foreground_store_or_path=foreground_path,
contours_store_or_path=contours_path,
)
4 changes: 2 additions & 2 deletions ultrack/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from ultrack.cli.estimate_params import estimate_params_cli
from ultrack.cli.export import export_cli
from ultrack.cli.flow import add_flow_cli
from ultrack.cli.labels_to_edges import labels_to_edges_cli
from ultrack.cli.labels_to_edges import labels_to_contours_cli
from ultrack.cli.link import link_cli
from ultrack.cli.segment import segmentation_cli
from ultrack.cli.server import server_cli
Expand All @@ -26,7 +26,7 @@ def main():
main.add_command(data_summary_cli)
main.add_command(estimate_params_cli)
main.add_command(export_cli)
main.add_command(labels_to_edges_cli)
main.add_command(labels_to_contours_cli)
main.add_command(link_cli)
main.add_command(segmentation_cli)
main.add_command(solve_cli)
Expand Down
24 changes: 12 additions & 12 deletions ultrack/cli/segment.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,18 @@ def _get_layer_data(viewer: ViewerModel, key: str) -> ArrayLike:
@napari_reader_option()
@config_option()
@click.option(
"--detection-layer",
"-dl",
"--foreground-layer",
"-fl",
required=True,
type=str,
help="Cell detection layer index on napari.",
help="Cell foreground layer index on napari.",
)
@click.option(
"--edge-layer",
"-el",
"--contours-layer",
"-cl",
required=True,
type=str,
help="Cell edges layer index on napari.",
help="Cell contours layer index on napari.",
)
@click.option(
"--insertion-throttle-rate",
Expand All @@ -57,8 +57,8 @@ def segmentation_cli(
paths: Sequence[Path],
reader_plugin: str,
config: MainConfig,
detection_layer: str,
edge_layer: str,
foreground_layer: str,
contours_layer: str,
insertion_throttle_rate: int,
batch_index: Optional[int],
overwrite: bool,
Expand All @@ -69,20 +69,20 @@ def segmentation_cli(
viewer = ViewerModel()
viewer.open(path=paths, plugin=reader_plugin)

detection = _get_layer_data(viewer, detection_layer)
edge = _get_layer_data(viewer, edge_layer)
foreground = _get_layer_data(viewer, foreground_layer)
edge = _get_layer_data(viewer, contours_layer)

if batch_index is None or batch_index == 0:
# this is not saved inside the `segment` function because this info
# isn't available there
config.data_config.metadata_add(
{"scale": viewer.layers[edge_layer].scale.tolist()}
{"scale": viewer.layers[contours_layer].scale.tolist()}
)

del viewer

segment(
detection,
foreground,
edge,
config,
batch_index=batch_index,
Expand Down
2 changes: 1 addition & 1 deletion ultrack/config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Configurations have default values, therefore you don't need to set them all fro
- max_area: Maximum segments area, regions larger than this value are removed;
- min_frontier: Minimum average contour value, neighboring regions with values below this are merged;
- max_noise: Upper limit of uniform distribution for additive noise on contour map;
- threshold: Threshold used to binary the cell detection map;
- threshold: Threshold used to binary the cell foreground map;
- ws_hierarchy: Watershed hierarchy function from [higra](https://higra.readthedocs.io/en/stable/python/watershed_hierarchy.html) used to construct the hierarchy;

- linking_config:
Expand Down
4 changes: 2 additions & 2 deletions ultrack/core/_test/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def test_tracking(
config_instance: MainConfig,
timelapse_mock_data: Tuple[zarr.Array, zarr.Array, zarr.Array],
) -> None:
detection, edges, labels = timelapse_mock_data
foreground, contours, labels = timelapse_mock_data

track(config_instance, labels=labels)
track(config_instance, detection=detection, edges=edges, overwrite=True)
track(config_instance, foreground=foreground, contours=contours, overwrite=True)
28 changes: 16 additions & 12 deletions ultrack/core/_test/test_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def test_track(
config_instance: MainConfig,
timelapse_mock_data: Tuple[zarr.Array, zarr.Array, zarr.Array],
) -> None:
detection, edges, labels = timelapse_mock_data
foreground, contours, labels = timelapse_mock_data

# 1st track call using labels
track(config_instance, labels=labels)
Expand All @@ -69,12 +69,12 @@ def test_track(
assert df_original.equals(df_tracker)
assert graph_original == graph_tracker

# 2nd track call using detection and edges
track(config_instance, detection=detection, edges=edges, overwrite=True)
# 2nd track call using foreground and contours
track(config_instance, foreground=foreground, contours=contours, overwrite=True)
df_original, graph_original = to_tracks_layer(config_instance)

tracker = ultrack.Tracker(config_instance)
tracker.track(detection=detection, edges=edges, overwrite=True)
tracker.track(foreground=foreground, contours=contours, overwrite=True)
df_tracker, graph_tracker = to_tracks_layer(config_instance)

assert df_original.equals(df_tracker)
Expand All @@ -93,16 +93,18 @@ def test_link_segment_and_solve(
config_instance: MainConfig,
timelapse_mock_data: Tuple[zarr.Array, zarr.Array, zarr.Array],
) -> None:
detection, edges, _ = timelapse_mock_data
foreground, contours, _ = timelapse_mock_data

tracker = ultrack.Tracker(config_instance)
tracker.segment(detection=detection, edges=edges)
tracker.segment(foreground=foreground, contours=contours)
tracker.link()
tracker.solve()

df, graph = to_tracks_layer(config_instance)

segment(detection=detection, edge=edges, config=config_instance, overwrite=True)
segment(
foreground=foreground, contours=contours, config=config_instance, overwrite=True
)
link(config_instance, overwrite=True)
solve(config_instance, overwrite=True)

Expand All @@ -126,10 +128,10 @@ def test_outputs(
tmp_path: str,
) -> None:
tmp_path = Path(tmp_path)
detection, edges, labels = timelapse_mock_data
foreground, contours, _ = timelapse_mock_data

tracker = ultrack.Tracker(config_instance)
tracker.segment(detection=detection, edges=edges)
tracker.segment(foreground=foreground, contours=contours)
tracker.link()
tracker.solve()

Expand Down Expand Up @@ -193,17 +195,19 @@ def test_flow(
timelapse_mock_data: Tuple[zarr.Array, zarr.Array, zarr.Array],
mock_flow_field: np.ndarray,
) -> None:
detection, edges, _ = timelapse_mock_data
foreground, contours, _ = timelapse_mock_data

tracker = ultrack.Tracker(config_instance)
tracker.segment(detection=detection, edges=edges)
tracker.segment(foreground=foreground, contours=contours)
tracker.add_flow(mock_flow_field)
tracker.link()
tracker.solve()

df, graph = to_tracks_layer(config_instance)

segment(detection=detection, edge=edges, config=config_instance, overwrite=True)
segment(
foreground=foreground, contours=contours, config=config_instance, overwrite=True
)
add_flow(config_instance, mock_flow_field)
link(config_instance, overwrite=True)
solve(config_instance, overwrite=True)
Expand Down
Loading

0 comments on commit 3d92c21

Please sign in to comment.