Skip to content

Conversation

@Jiaqi-Lv
Copy link
Collaborator

@Jiaqi-Lv Jiaqi-Lv commented Nov 6, 2025

This PR defines a new NucleusDetector engine. It would be used by nucleus detection models such as MapDe and KongNet.

After having obtained the WSI-level segmentation map (dask array from SemanticSegmentor.infer_wsi()), we use dask map_overlap to map the model's postproc function across the entire WSI segmentation map, map_overlap allows the postproc function to be executed in parallel then automatically then merges the results back into dask array -> "detection_map".
The "detection_map" has the same dimensions as the segmentation map, but the nuclei centroids would have the values of the detection probability, if the model does not produce detection probability then it is set to 1.
The "detection_map" is converted into "detection_records" using dask map_blocks, which processes chunks in parallel, each chunk would be processed into a tuple of numpy arrays: [[x_coords], [y_coords], [class_ids], [probs]] representing the detected nuclei; then the records are saved into SQLiteStore chunk by chunk.

Currently it only saves the results as SQLiteStore.

  • Copy code from the old PR over so we can close the old PR ✨ NEW: Add Nucleus Detection Engine #538.
  • Add NucleusDetector engine
  • Update existing detection models (mapde is done, sccnn has bug)
  • Test "patch mode" inference
  • Add unit tests

@Jiaqi-Lv Jiaqi-Lv added the enhancement New feature or request label Nov 6, 2025
@shaneahmed
Copy link
Member

This PR will take over #538

@Jiaqi-Lv Jiaqi-Lv marked this pull request as draft November 7, 2025 17:29
@Jiaqi-Lv Jiaqi-Lv self-assigned this Nov 7, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces a new NucleusDetector engine for nucleus detection models (MapDe, SCCNN) that processes whole slide images (WSI) using Dask for parallel processing. The detection pipeline performs WSI-level segmentation, applies post-processing via map_overlap, and converts results to detection records stored in SQLiteStore.

Key Changes:

  • New NucleusDetector class extending SemanticSegmentor with specialized post-processing for nucleus detection
  • Modified postproc methods in MapDe and SCCNN models to support chunk-based processing with Dask
  • Updated model configurations to include postproc_tile_shape parameter and corrected ioconfig class paths

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 14 comments.

Show a summary per file
File Description
tiatoolbox/models/engine/nucleus_detector.py New NucleusDetector engine with methods for WSI-level detection, NMS, chunk processing, and AnnotationStore conversion
tiatoolbox/models/engine/engine_abc.py Updated ProgressBar import path to use specific module
tiatoolbox/models/engine/init.py Added nucleus_detector to module exports
tiatoolbox/models/architecture/sccnn.py Refactored postproc method for Dask compatibility, updated infer_batch return type, added postproc_tile_shape parameter
tiatoolbox/models/architecture/mapde.py Refactored postproc method for Dask compatibility, updated infer_batch return type, added postproc_tile_shape parameter
tiatoolbox/data/pretrained_model.yaml Added postproc_tile_shape to model configs, corrected ioconfig class paths, removed tile_shape from ioconfig sections
tests/engines/test_nucleus_detection_engine.py Placeholder test file with commented-out test cases (needs implementation)
test.py Temporary test script with hardcoded paths (should be removed or gitignored)
docs/pretrained.rst Corrected resolution values from 0.25 to 0.5 mpp in ioconfig examples
Comments suppressed due to low confidence (4)

tiatoolbox/models/engine/nucleus_detector.py:286

  • Variable r2 is not used.
        r2 = float(radius) * float(radius)

tiatoolbox/models/engine/nucleus_detector.py:221

  • This assignment to 'scale_factor' is unnecessary as it is redefined before this value is used.
        scale_factor = kwargs.get("scale_factor", (1.0, 1.0))

tiatoolbox/models/engine/nucleus_detector.py:223

  • This assignment to 'class_dict' is unnecessary as it is redefined before this value is used.
        class_dict = kwargs.get("class_dict")

tiatoolbox/models/engine/nucleus_detector.py:285

  • This assignment to 'coords' is unnecessary as it is redefined before this value is used.
        coords = sub[["x", "y"]].to_numpy(dtype=np.float64)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@codecov
Copy link

codecov bot commented Nov 23, 2025

Codecov Report

❌ Patch coverage is 97.83784% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 94.90%. Comparing base (e24b9e8) to head (79fc088).

Files with missing lines Patch % Lines
tiatoolbox/models/engine/nucleus_detector.py 97.14% 2 Missing and 2 partials ⚠️
Additional details and impacted files
@@                    Coverage Diff                     @@
##           dev-define-engines-abc     #967      +/-   ##
==========================================================
+ Coverage                   94.85%   94.90%   +0.05%     
==========================================================
  Files                          75       76       +1     
  Lines                        9477     9651     +174     
  Branches                     1238     1263      +25     
==========================================================
+ Hits                         8989     9159     +170     
- Misses                        452      454       +2     
- Partials                       36       38       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Jiaqi-Lv Jiaqi-Lv marked this pull request as ready for review November 27, 2025 16:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants