"""The ONE entrypoint a tool author edits. `process(image_path, engine, diameter)` segments cells/nuclei and returns an overlay summary image + a report. `simulate_full` also returns the raw result. """ from __future__ import annotations import os import numpy as np from . import fast_seg, viz from .io import load_image ENGINES = ["fast", "cellpose"] def simulate_full(image_path: str, engine: str = "fast", diameter: float = 0.0) -> dict: if engine not in ENGINES: raise ValueError(f"Unknown engine '{engine}'. Choose one of {ENGINES}.") img = load_image(image_path) # Use ground-truth labels if a sidecar exists (the baked example) to score. gt = None side = os.path.splitext(str(image_path))[0] + "_labels.npy" if os.path.exists(side): try: gt = np.load(side) except Exception: # noqa: BLE001 gt = None if engine == "cellpose": from . import cellpose_engine res = cellpose_engine.analyze(img, diameter=float(diameter), gt=gt) else: md = int(diameter / 2) if diameter else 8 res = fast_seg.analyze(img, min_distance=max(3, md), gt=gt) return {"summary": viz.summary_image(res), "report": res["report"], "res": res} def process(image_path: str, engine: str = "fast", diameter: float = 0.0) -> tuple[np.ndarray, dict]: """Returns (segmentation overlay RGB, report dict).""" r = simulate_full(image_path, engine, diameter) return r["summary"], r["report"]