@@ -616,6 +616,87 @@ def test_workflow_bounding_box_with_overlap(
616
616
assert "bounding-box pairs overlap" in caplog .text
617
617
618
618
619
+ def test_cellpose_within_masked_bb_with_overlap (
620
+ tmp_path : Path ,
621
+ zenodo_zarr : list [str ],
622
+ caplog : pytest .LogCaptureFixture ,
623
+ monkeypatch : MonkeyPatch ,
624
+ ):
625
+ """
626
+ Test to address #785: Segmenting objects within a masking ROI table and
627
+ ensuring that the relabeling works well with the masking.
628
+ """
629
+
630
+ monkeypatch .setattr (
631
+ "fractal_tasks_core.tasks.cellpose_segmentation.cellpose.core.use_gpu" ,
632
+ patched_cellpose_core_use_gpu ,
633
+ )
634
+
635
+ monkeypatch .setattr (
636
+ "fractal_tasks_core.tasks.cellpose_segmentation.segment_ROI" ,
637
+ patched_segment_ROI_overlapping_organoids ,
638
+ )
639
+
640
+ # Setup caplog fixture, see
641
+ # https://docs.pytest.org/en/stable/how-to/logging.html#caplog-fixture
642
+ caplog .set_level (logging .WARNING )
643
+
644
+ # Use pre-made 3D zarr
645
+ zarr_dir = tmp_path / "tmp_out/"
646
+ zarr_urls = prepare_3D_zarr (str (zarr_dir ), zenodo_zarr )
647
+ debug (zarr_dir )
648
+ debug (zarr_urls )
649
+
650
+ # Per-FOV labeling
651
+ channel = CellposeChannel1InputModel (
652
+ wavelength_id = "A01_C01" , normalize = CellposeCustomNormalizer ()
653
+ )
654
+ for zarr_url in zarr_urls :
655
+ cellpose_segmentation (
656
+ zarr_url = zarr_url ,
657
+ channel = channel ,
658
+ level = 3 ,
659
+ relabeling = True ,
660
+ diameter_level0 = 80.0 ,
661
+ output_label_name = "initial_segmentation" ,
662
+ output_ROI_table = "bbox_table" ,
663
+ )
664
+
665
+ # Assert that 4 unique labels + background are present in the
666
+ # initial_segmentation
667
+ import dask .array as da
668
+
669
+ initial_segmentation = da .from_zarr (
670
+ f"{ zarr_urls [0 ]} /labels/initial_segmentation/0"
671
+ ).compute ()
672
+ assert len (np .unique (initial_segmentation )) == 5
673
+ assert np .max (initial_segmentation ) == 4
674
+
675
+ # Segment objects within the bbox_table masked, ensure the relabeling
676
+ # happens correctly
677
+ for zarr_url in zarr_urls :
678
+ cellpose_segmentation (
679
+ zarr_url = zarr_url ,
680
+ channel = channel ,
681
+ level = 3 ,
682
+ relabeling = True ,
683
+ diameter_level0 = 80.0 ,
684
+ input_ROI_table = "bbox_table" ,
685
+ output_label_name = "secondary_segmentation" ,
686
+ output_ROI_table = "secondary_ROI_table" ,
687
+ )
688
+ # Check labels in secondary_segmentation: Verify correctness
689
+ # Our monkeypatched segmentation returns 2 labels, only 1 of which is
690
+ # within the mask => should be 1 segmentation output per initial object
691
+ # If relabeling works correctly, there will be 4 objects in
692
+ # secondary_segmentation and they will be 1, 2, 3, 4
693
+ initial_segmentation = da .from_zarr (
694
+ f"{ zarr_urls [0 ]} /labels/secondary_segmentation/0"
695
+ ).compute ()
696
+ assert len (np .unique (initial_segmentation )) == 5
697
+ assert np .max (initial_segmentation ) == 4
698
+
699
+
619
700
def test_workflow_with_per_FOV_labeling_via_script (
620
701
tmp_path : Path ,
621
702
zenodo_zarr : list [str ],
0 commit comments