phenotypic.abc_.GpuDetector#

class phenotypic.abc_.GpuDetector(*args, **kwargs)[source]

Bases: ObjectDetector, ABC

Marker ABC for object detectors that require GPU acceleration.

Subclass GpuDetector when your detection algorithm depends on a GPU (e.g., deep-learning foundation models like SAM2 or micro-sam).

When a pipeline contains a GpuDetector, the CLI enforces:

  • Local execution: Sequential processing (n_jobs=1) to avoid multiple workers competing for the same GPU.

  • SLURM execution: Automatically requests GPU resources (--gpus-per-node=1) if the user hasn’t specified GPU args. Raises an error if the target partition has no GPUs.

  • No GPU available: Raises RuntimeError at pipeline validation time with a clear message.

When to subclass GpuDetector vs ObjectDetector

Subclass GpuDetector if your detector relies on GPU-accelerated inference:

  • Deep-learning models (SAM2, micro-sam, or custom neural networks).

  • Any algorithm that requires torch, tensorflow, or similar GPU-backed frameworks at inference time.

  • Detectors where CPU fallback is technically possible but impractically slow for production use.

Subclass ObjectDetector directly if your algorithm is CPU-based:

  • Classical computer vision (thresholding, edge detection, watershed).

  • Algorithms implemented with NumPy, SciPy, or scikit-image.

  • Detectors that run in milliseconds on CPU.

Lazy model loading

GpuDetector subclasses should defer model construction to the first apply() call rather than __init__(). This enables:

  • Fast construction and serialization round-trips without GPU/torch.

  • Pipeline to_json()/from_json() without importing heavy dependencies.

  • Parameter inspection and validation before committing GPU memory.

Use a _ensure_model_loaded() pattern:

class MyGpuDetector(GpuDetector):
    def __init__(self, model_size="small", device="auto"):
        super().__init__()
        self.model_size = model_size
        self.device = device
        self._model = None  # underscore prefix → skipped by serialization

    def _ensure_model_loaded(self):
        if getattr(self, "_model", None) is not None:
            return
        import torch  # lazy import
        # ... build model ...

    def _operate(self, image):
        self._ensure_model_loaded()
        # ... run inference ...
        return image

Notes

This is a marker ABC with no additional methods beyond those inherited from ObjectDetector. It exists to categorize GPU-requiring detectors in the class hierarchy and enable the CLI to make informed resource-allocation decisions.

Methods

__init__

apply

Detect colonies using sinusoidal cross-correlation grid estimation.

widget

Return (and optionally display) the root widget.

__del__()

Automatically stop tracemalloc when the object is deleted.

__getstate__()

Prepare the object for pickling by disposing of any widgets.

This ensures that UI components (which may contain unpickleable objects like input functions or thread locks) are cleaned up before serialization.

Note

This method modifies the object state by calling dispose_widgets(). Any active widgets will be detached from the object.

apply(image, inplace=False)

Detect colonies using sinusoidal cross-correlation grid estimation.

This method performs the core detection workflow: 1. Extract grid dimensions (if GridImage) 2. Threshold the detection matrix with adaptive kernel sizing 3. Remove noise if requested 4. Label connected components 5. Determine or estimate grid edges (via sinusoidal cross-correlation) 6. Assign dominant colonies to grid cells 7. Create final object map

Parameters:

image – Image object to process. Can be a regular Image or GridImage.

Returns:

The processed image with updated objmask and objmap.

Return type:

Image

widget(image: Image | None = None, show: bool = False) Widget

Return (and optionally display) the root widget.

Parameters:
  • image (Image | None) – Optional image to visualize. If provided, visualization controls will be added to the widget.

  • show (bool) – Whether to display the widget immediately. Defaults to False.

Returns:

The root widget.

Return type:

ipywidgets.Widget

Raises:

ImportError – If ipywidgets or IPython are not installed.