magscope.auto_bead_selection
============================

.. py:module:: magscope.auto_bead_selection


Attributes
----------

.. autoapisummary::

   magscope.auto_bead_selection._DEFAULT_CORRELATION_CHUNK_ROWS
   magscope.auto_bead_selection._CANDIDATE_PROGRESS_UPDATE_INTERVAL
   magscope.auto_bead_selection._MIN_CANDIDATE_SCORE


Exceptions
----------

.. autoapisummary::

   magscope.auto_bead_selection.AutoBeadSearchCancelled


Classes
-------

.. autoapisummary::

   magscope.auto_bead_selection.AutoBeadCandidate


Functions
---------

.. autoapisummary::

   magscope.auto_bead_selection.copy_latest_image
   magscope.auto_bead_selection.crop_roi
   magscope.auto_bead_selection.normalized_cross_correlation
   magscope.auto_bead_selection._ones_kernel
   magscope.auto_bead_selection._correlate2d_valid_chunked
   magscope.auto_bead_selection._window_sum_integral
   magscope.auto_bead_selection._mark_blocked_roi
   magscope.auto_bead_selection.normalized_cross_correlation_chunked
   magscope.auto_bead_selection.roi_overlaps
   magscope.auto_bead_selection.roi_is_within_image
   magscope.auto_bead_selection.filter_candidates_by_score_threshold
   magscope.auto_bead_selection.default_candidate_score_threshold
   magscope.auto_bead_selection.detect_matching_beads
   magscope.auto_bead_selection.run_auto_bead_search_process


Module Contents
---------------

.. py:data:: _DEFAULT_CORRELATION_CHUNK_ROWS
   :value: 20


.. py:data:: _CANDIDATE_PROGRESS_UPDATE_INTERVAL
   :value: 512


.. py:data:: _MIN_CANDIDATE_SCORE

.. py:exception:: AutoBeadSearchCancelled

   Bases: :py:obj:`RuntimeError`


   Raised when auto bead matching is canceled between correlation chunks.


.. py:class:: AutoBeadCandidate

   .. py:attribute:: roi
      :type:  tuple[int, int, int, int]


   .. py:attribute:: score
      :type:  float


.. py:function:: copy_latest_image(image_bytes: memoryview | bytes | bytearray, image_shape: tuple[int, int], dtype: numpy.dtype) -> numpy.ndarray

   Copy a recent image snapshot in the same orientation shown in the UI.


.. py:function:: crop_roi(image: numpy.ndarray, roi: tuple[int, int, int, int]) -> numpy.ndarray

   Return the ROI crop from a viewer-oriented ``(height, width)`` image.


.. py:function:: normalized_cross_correlation(image: numpy.ndarray, template: numpy.ndarray) -> numpy.ndarray

   Compute 2D normalized cross-correlation over valid ROI-sized positions.


.. py:function:: _ones_kernel(shape: tuple[int, int]) -> numpy.ndarray

.. py:function:: _correlate2d_valid_chunked(image: numpy.ndarray, kernel: numpy.ndarray, *, chunk_rows: int, cancel_check: collections.abc.Callable[[], bool] | None = None, progress_callback: collections.abc.Callable[[int, int], None] | None = None) -> numpy.ndarray

   Compute ``correlate2d(..., mode='valid')`` in row stripes.


.. py:function:: _window_sum_integral(image: numpy.ndarray, window_shape: tuple[int, int]) -> numpy.ndarray

   Compute valid sliding-window sums via a summed-area table.


.. py:function:: _mark_blocked_roi(blocked_mask: numpy.ndarray, roi: tuple[int, int, int, int], roi_size: tuple[int, int]) -> None

   Mark all top-left positions whose ROI would overlap ``roi``.


.. py:function:: normalized_cross_correlation_chunked(image: numpy.ndarray, template: numpy.ndarray, *, chunk_rows: int = _DEFAULT_CORRELATION_CHUNK_ROWS, cancel_check: collections.abc.Callable[[], bool] | None = None, progress_callback: collections.abc.Callable[[int, int], None] | None = None) -> numpy.ndarray

   Compute 2D normalized cross-correlation over valid ROI-sized positions.


.. py:function:: roi_overlaps(roi_a: tuple[int, int, int, int], roi_b: tuple[int, int, int, int]) -> bool

.. py:function:: roi_is_within_image(roi: tuple[int, int, int, int], image_shape: tuple[int, int]) -> bool

.. py:function:: filter_candidates_by_score_threshold(candidates: Iterable[AutoBeadCandidate], threshold: float) -> list[AutoBeadCandidate]

.. py:function:: default_candidate_score_threshold(candidates: Iterable[AutoBeadCandidate]) -> float

   Choose a default score threshold that favors the strongest score cluster.


.. py:function:: detect_matching_beads(image: numpy.ndarray, seed_roi: tuple[int, int, int, int], existing_rois: Iterable[tuple[int, int, int, int]], *, chunk_rows: int = _DEFAULT_CORRELATION_CHUNK_ROWS, cancel_check: collections.abc.Callable[[], bool] | None = None, progress_callback: collections.abc.Callable[[int, int], None] | None = None) -> tuple[numpy.ndarray, list[AutoBeadCandidate]]

   Detect non-overlapping ROI candidates that match the seed ROI template.


.. py:function:: run_auto_bead_search_process(request_queue, result_queue, active_request_id: multiprocessing.sharedctypes.Synchronized, *, chunk_rows: int = _DEFAULT_CORRELATION_CHUNK_ROWS) -> None

   Serve auto-bead search requests from a temporary worker process.


