Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
172 commits
Select commit Hold shift + click to select a range
4d21d22
:new: Define New MultiTaskSegmentor
shaneahmed Jan 8, 2026
fef42ea
:construction: Add functionalities
shaneahmed Jan 8, 2026
ab5cf7c
:fire: Remove previous codes
shaneahmed Jan 8, 2026
eab6db0
:fire: Remove previous codes
shaneahmed Jan 8, 2026
f8ff99c
:white_check_mark: Add initialization test
shaneahmed Jan 8, 2026
17c7a8a
:boom: Add patch segmentation test
shaneahmed Jan 8, 2026
ced4924
:boom: Update loop for postprocessing
shaneahmed Jan 8, 2026
8ea1056
:boom: Work in progress
shaneahmed Jan 9, 2026
1b9d254
Merge branch 'dev-define-engines-abc' into dev-define-multitask-segme…
shaneahmed Jan 9, 2026
335aa07
:construction: Update multitask post processing outputs.
shaneahmed Jan 9, 2026
3447495
:construction: Update postprocessing to incorporate dictionary outputs
shaneahmed Jan 12, 2026
84a717d
:white_check_mark: Add test for dictionary output
shaneahmed Jan 12, 2026
6065409
:bug: Fix hovernet and hovernetplus tests
shaneahmed Jan 12, 2026
1c6619b
Merge branch 'dev-define-engines-abc' into dev-define-multitask-segme…
shaneahmed Jan 12, 2026
bd6d4b7
:white_check_mark: Add tests for zarr output
shaneahmed Jan 12, 2026
c7238b2
:bug: Fix deepsource errors
shaneahmed Jan 12, 2026
fa3dcc1
:white_check_mark: Add test for single output.
shaneahmed Jan 13, 2026
b042e86
:white_check_mark: Add test for save_dir and None output_type
shaneahmed Jan 13, 2026
47efdd1
:white_check_mark: Improve test coverage.
shaneahmed Jan 13, 2026
618f123
Merge branch 'dev-define-engines-abc' into dev-define-multitask-segme…
shaneahmed Jan 13, 2026
645986d
:white_check_mark: Add test for annotationstore single output.
shaneahmed Jan 13, 2026
d9953cc
Merge branch 'dev-define-engines-abc' into dev-define-multitask-segme…
shaneahmed Jan 13, 2026
e86e176
:white_check_mark: Add tests for multitask annotation store
shaneahmed Jan 13, 2026
4247afa
:white_check_mark: Test output of layer and nuclei segmentation for a…
shaneahmed Jan 13, 2026
94f427e
:white_check_mark: Test output of layer and nuclei segmentation for a…
shaneahmed Jan 13, 2026
b16b57b
:bug: Read image at correct resolution
shaneahmed Jan 13, 2026
8aebbaf
:bug: Fix saving annotationstore using zarr
shaneahmed Jan 13, 2026
e4392c9
:white_check_mark: Add test for logger.
shaneahmed Jan 13, 2026
f9f5f69
:bug: Fix deepsource error `PTC-W0060`
shaneahmed Jan 14, 2026
84a4611
:white_check_mark: Use file paths for a test
shaneahmed Jan 14, 2026
6e1b55f
:bug: Fix paths to input files in test
shaneahmed Jan 14, 2026
99e2352
Merge branch 'dev-define-engines-abc' into dev-define-multitask-segme…
shaneahmed Jan 14, 2026
ff804db
:construction: Add zarr output for WSIs
shaneahmed Jan 16, 2026
04dada4
:bug: Fix deepsource error
shaneahmed Jan 19, 2026
a8ca393
:bug: Fix deepsource error
shaneahmed Jan 19, 2026
a336569
add type annotation utils.transforms.py
Jiaqi-Lv Jan 19, 2026
5717512
:sparkles: Add WSI AnnotationStore support
shaneahmed Jan 19, 2026
568964d
:white_check_mark: Add check for single task and class_dict
shaneahmed Jan 19, 2026
943aebf
:white_check_mark: Add check for single task and class_dict support
shaneahmed Jan 19, 2026
e3830b1
:bug: Fix PY-W0070 deep source error
shaneahmed Jan 19, 2026
528b72e
:zap: Use smaller images for faster test runs.
shaneahmed Jan 19, 2026
8e5578a
:bug: Fix memory check for saving arrays
shaneahmed Jan 20, 2026
60faab5
:lipstick: Update logic for better readability
shaneahmed Jan 20, 2026
ddc2a54
:bug: Remove residual canvas and count keys
shaneahmed Jan 20, 2026
8cd457c
:bug: Fix deepsource errors
shaneahmed Jan 20, 2026
e715f1b
Merge branch 'dev-define-engines-abc' into dev-define-multitask-segme…
shaneahmed Jan 22, 2026
4bb4900
:bug: Fix count in merge_predictions
shaneahmed Jan 23, 2026
5e659c0
:bug: Fix count in merge_predictions
shaneahmed Jan 23, 2026
c0decb6
:bug: Fix HoVerNetPlus postprocessing.
shaneahmed Jan 25, 2026
d934167
:construction: Merge using tile outputs.
shaneahmed Jan 26, 2026
e660bb3
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 26, 2026
be79c7f
[skip ci] :construction: Restructure dictionary output
shaneahmed Jan 26, 2026
55f7d7f
[skip ci] :construction: Fix structure of the output
shaneahmed Jan 26, 2026
7a2fb6c
[skip ci] :construction: Fix structure of the output
shaneahmed Jan 26, 2026
e63385d
Merge branch 'dev-define-engines-abc' into dev-define-multitask-segme…
shaneahmed Jan 28, 2026
189d5b3
:memo: Add docstring for `_get_inst_info_dicts`
shaneahmed Jan 29, 2026
13aa48c
:construction: Working on testing tile based output
shaneahmed Jan 29, 2026
44456a7
:construction: Finalise wsi_info_dict structure to work with save_pre…
shaneahmed Jan 29, 2026
4dbf9c4
:white_check_mark: Update hovernet postprocessing to be compatible wi…
shaneahmed Jan 29, 2026
eb60aa1
:construction: Initial implementation of merged predictions
shaneahmed Jan 30, 2026
820bb6e
:construction: Initial implementation of merged predictions
shaneahmed Jan 30, 2026
30c2ae7
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 30, 2026
2c0dccd
:white_check_mark: Add support for tile based "predictions" output
shaneahmed Jan 30, 2026
c963514
:white_check_mark: Add support for tile based "predictions" output
shaneahmed Jan 30, 2026
0aaaf5b
:bug: Fix deepsource error
shaneahmed Jan 30, 2026
e3f9458
:bug: Fix deepsource error
shaneahmed Jan 30, 2026
f5fe072
:bug: Fix `mypy` error
shaneahmed Jan 30, 2026
4683416
:bug: Fix deepsource errors
shaneahmed Jan 30, 2026
af8b67b
:bug: Fix coverage for `misc.py`
shaneahmed Jan 30, 2026
5820182
:bug: Fix coverage for `multi_task_segmentor.py`
shaneahmed Jan 30, 2026
ce865bd
:memo: Update docstrings.
shaneahmed Jan 30, 2026
260bbc9
:memo: Update docstrings.
shaneahmed Jan 30, 2026
21b3398
:memo: Update docstrings.
shaneahmed Jan 30, 2026
c6b7d72
:memo: Update docstrings.
shaneahmed Jan 30, 2026
c2f0ac6
:memo: Update docstrings.
shaneahmed Jan 30, 2026
d8ed2f5
:pushpin: Pin `dask>=2026.1.2`
shaneahmed Jan 30, 2026
ccc7fd4
:white_check_mark: Add CLI support.
shaneahmed Jan 31, 2026
4ac2ef4
:white_check_mark: Update CLI tests.
shaneahmed Jan 31, 2026
1cbb01b
:bug: Fix ARG001 error
shaneahmed Jan 31, 2026
7801944
:bug: Fix deepsource and `mypy` errors.
shaneahmed Jan 31, 2026
60852ea
Merge branch 'dev-define-engines-abc' into dev-define-multitask-segme…
shaneahmed Jan 31, 2026
3cf8504
:green_heart: Address Co-Pilot review comments.
shaneahmed Feb 2, 2026
1e52eca
Merge branch 'dev-define-engines-abc' into dev-define-multitask-segme…
shaneahmed Feb 2, 2026
9ecddab
Merge branch 'dev-define-engines-abc' into dev-define-multitask-segme…
shaneahmed Feb 3, 2026
46eb4dc
:green_heart: Address Co-Pilot comments
shaneahmed Feb 3, 2026
a60b50f
:zap: Use `prepare_full_batch` from `semantic_segmentor`.
shaneahmed Feb 3, 2026
3a68f0a
:zap: Use `save_to_cache` from `semantic_segmentor`.
shaneahmed Feb 3, 2026
1836816
:zap: Use `max(vm.available, 1)` to calculate memory usage.
shaneahmed Feb 3, 2026
9fb9ea6
:zap: Use `merge_horizontal` from `semantic_segmentor`.
shaneahmed Feb 3, 2026
f7e35be
:bug: Fix saving and deletion of temp_zarr name.
shaneahmed Feb 3, 2026
dd3e5a5
:white_check_mark: Use `hovernet_original-kumar`
shaneahmed Feb 3, 2026
27d6161
:white_check_mark: Update `NucleusInstanceSegmentor`.
shaneahmed Feb 3, 2026
86111a6
:white_check_mark: Add tests for io_config.
shaneahmed Feb 3, 2026
de65370
:white_check_mark: Add `cli` for `nucleus_instance_segmentor`.
shaneahmed Feb 3, 2026
52e21e6
:white_check_mark: Add tests for cli
shaneahmed Feb 3, 2026
151b61e
:white_check_mark: Add tests for cli coverage.
shaneahmed Feb 3, 2026
6015d5f
:white_check_mark: Add progress bar for saving annotationstore.
shaneahmed Feb 4, 2026
a0ae9d1
:white_check_mark: Update ioconfig
shaneahmed Feb 4, 2026
f48c4e0
:white_check_mark: Update batchsize for cli and tests
shaneahmed Feb 4, 2026
e962fe5
:bug: Fix deepsource bug
shaneahmed Feb 4, 2026
73f7d61
:bug: Fix tests
shaneahmed Feb 5, 2026
aae3529
:lipstick: Update description for tqdm
shaneahmed Feb 5, 2026
322f4f6
:lipstick: Update description for tqdm
shaneahmed Feb 5, 2026
7c62b3d
:white_check_mark: Add tests for improved coverage
shaneahmed Feb 5, 2026
199aeb9
:zap: Use dask delayed for parallel post-processing.
shaneahmed Feb 5, 2026
20a2a84
:lipstick: Replace `tqdm.write` with `tqdm.desc`
shaneahmed Feb 6, 2026
63d9157
:bug: Fix failing test for DummyTQDM
shaneahmed Feb 6, 2026
9fda536
:zap: Use dask delayed to save annotations.
shaneahmed Feb 6, 2026
bbb1bbf
:lipstick: Add tqdm to creating list of tasks
shaneahmed Feb 6, 2026
2684d92
:lipstick: Update `warnings` and `tqdm`.
shaneahmed Feb 7, 2026
a1ee82d
:bug: Fix test with same input and output directory.
shaneahmed Feb 7, 2026
8318a14
:recycle: Restructure calculation of delayed objects
shaneahmed Feb 7, 2026
bcbfb1a
:zap: Pass only small arrays to delayed function
shaneahmed Feb 7, 2026
cbc27b9
:bug: Fix deep source error.
shaneahmed Feb 7, 2026
ae09e90
:lipstick: Update tqdm
shaneahmed Feb 7, 2026
6b320cd
:zap: Test computation of arrays using dask delayed.
shaneahmed Feb 7, 2026
eaa13af
:zap: Test computation of arrays using dask delayed.
shaneahmed Feb 7, 2026
199674c
:bug: Fix tqdm_loop
shaneahmed Feb 7, 2026
11513d6
:lipstick: Update tqdm loop engine_abc.py
shaneahmed Feb 7, 2026
ca55c74
:lipstick: Update tqdm loop semantic_segmentor.py
shaneahmed Feb 7, 2026
0ba7627
:lipstick: Update tqdm loop semantic_segmentor.py
shaneahmed Feb 7, 2026
9a03550
:lipstick: Use `get_tqdm_full` for nucleus_detector.py
shaneahmed Feb 7, 2026
1480c2c
:lipstick: Use `get_tqdm_full` for nucleus_detector.py
shaneahmed Feb 7, 2026
6fb8293
:bug: Fix `mypy` errors.
shaneahmed Feb 7, 2026
1fc69d7
:zap: Try computing full array
shaneahmed Feb 8, 2026
628cdd0
:lipstick: Use tqdm progress bar for dask
shaneahmed Feb 8, 2026
b7df2e0
:lipstick: Use tqdm.dask progress bar for dask
shaneahmed Feb 8, 2026
69fa82d
:bug: Fix delayed_tasks compute
shaneahmed Feb 8, 2026
0b91f28
:recycle: Add `tqdm_dask_progress_bar`
shaneahmed Feb 8, 2026
dba148f
:zap: Optimise performance and move tqdm progress bar to misc
shaneahmed Feb 9, 2026
af5d598
:zap: Tile based processing is faster
shaneahmed Feb 9, 2026
8741c93
:bug: Fix memory threshold variable.
shaneahmed Feb 9, 2026
3fd396b
:bug: Update appropriate tile_shape
shaneahmed Feb 9, 2026
239b434
:zap: Optimise by removing unnecessary dask compute
shaneahmed Feb 9, 2026
dcd7384
:bug: Fix outputs for annotationstore with multiple inputs.
shaneahmed Feb 9, 2026
bc86d74
:fire: Remove unnecessary variables
shaneahmed Feb 9, 2026
5d26867
:bug: Fix writing annotations for large images
shaneahmed Feb 11, 2026
90e3fd5
:zap: Improve annotationstore writing
shaneahmed Feb 11, 2026
787c489
:bug: Fix output annotation type
shaneahmed Feb 11, 2026
bd28991
:zap: Use vectorized shapely.box instead of shapely.geometry.box
shaneahmed Feb 11, 2026
476a365
:bulb: Address review comments
shaneahmed Feb 12, 2026
de2c899
:bug: Fix deepsource error
shaneahmed Feb 12, 2026
5137f6f
:lipstick: Set `leave=False` for tqdm loops
shaneahmed Feb 12, 2026
6e7597e
:bug: Fix multi-gpu run
shaneahmed Feb 12, 2026
ba7f5d2
:zap: Convert to annotationstore from memory
shaneahmed Feb 12, 2026
0328ba9
:construction: Add qupath json
shaneahmed Feb 13, 2026
892a08f
:bulb: Address review comments
shaneahmed Feb 13, 2026
1f0d0e0
Merge branch 'dev-define-engines-abc' into dev-define-multitask-segme…
shaneahmed Feb 13, 2026
34c63ef
:sparkles: Add support for `qupath` output
shaneahmed Feb 13, 2026
4ee26d9
update tiatoolbox/utils/misc.py
Jiaqi-Lv Feb 13, 2026
1cdcd76
:bug: Fix deep-source errors
shaneahmed Feb 13, 2026
21cdd9a
:bug: Fix `mypy` errors
shaneahmed Feb 13, 2026
e1862eb
Merge branch 'dev-define-engines-abc' into dev-define-multitask-segme…
shaneahmed Feb 14, 2026
101845d
Merge branch 'dev-define-engines-abc' into dev-add-qupathjson
shaneahmed Feb 14, 2026
e98d1a1
:bug: Allow "qupath" output_type.
shaneahmed Feb 14, 2026
8e2c620
:sparkles: Add support for QuPath output in semantic_segmentor.py
shaneahmed Feb 14, 2026
3e3207b
:bug: Fix tests and `mypy` errors
shaneahmed Feb 14, 2026
c82273f
:bug: Fix `mypy` errors
shaneahmed Feb 14, 2026
607be4a
:recycle: Restructure code to avoid duplicates.
shaneahmed Feb 15, 2026
18b8fcd
:sparkles: Add `QuPath` support for nucleus detection.
shaneahmed Feb 15, 2026
7441f99
:bug: Fix deepsource error
shaneahmed Feb 15, 2026
4641ab3
:twisted_rightwards_arrows: Merge branch 'dev-define-engines-abc' int…
shaneahmed Feb 16, 2026
fb39268
Merge branch 'dev-define-engines-abc' into dev-define-multitask-segme…
shaneahmed Feb 16, 2026
f141549
:twisted_rightwards_arrows: Merge branch 'dev-define-engines-abc' int…
shaneahmed Feb 16, 2026
b6f6e41
Merge branch 'dev-define-multitask-segmentor' into dev-add-qupathjson
shaneahmed Feb 16, 2026
459c9ed
:white_check_mark: Improve tests
shaneahmed Feb 16, 2026
ecc84e1
:sparkles: Add `qupath` output to multitask segmentor
shaneahmed Feb 16, 2026
b4991a2
:bulb: Address Co-Pilot comments.
shaneahmed Feb 17, 2026
c3a6c65
:white_check_mark: Add tests for coverage.
shaneahmed Feb 17, 2026
acafdd9
:white_check_mark: Add tests to validate QuPath output.
shaneahmed Feb 17, 2026
be10ef4
:bug: Fix tests
shaneahmed Feb 17, 2026
82d8454
:bug: Fix deepsource error.
shaneahmed Feb 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 33 additions & 43 deletions tests/engines/test_engine_abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def test_incorrect_output_type() -> None:

with pytest.raises(
TypeError,
match=r".*output_type must be 'dict' or 'zarr' or 'annotationstore*",
match=r".*output_type must be 'dict' or 'zarr', 'qupath' or 'annotationstore*",
):
_ = eng.run(
images=np.zeros((10, 224, 224, 3), dtype=np.uint8),
Expand All @@ -77,6 +77,38 @@ def test_incorrect_output_type() -> None:
)


def test_incorrect_output_type_save_dir() -> None:
"""Test EngineABC for None output_type and output type zarr/annotationstore."""
pretrained_model = "alexnet-kather100k"

# Test engine run without ioconfig
eng = TestEngineABC(model=pretrained_model)

with pytest.raises(
ValueError,
match=r".*Please provide save_dir for output_type=zarr*",
):
_ = eng.run(
images=np.zeros((10, 224, 224, 3), dtype=np.uint8),
device=device,
patch_mode=True,
ioconfig=None,
output_type="zarr",
)

with pytest.raises(
ValueError,
match=r".*Please provide save_dir for output_type=annotationstore*",
):
_ = eng.run(
images=np.zeros((10, 224, 224, 3), dtype=np.uint8),
device=device,
patch_mode=True,
ioconfig=None,
output_type="annotationstore",
)


def test_pretrained_ioconfig() -> None:
"""Test EngineABC initialization with pretrained model name in the toolbox."""
pretrained_model = "alexnet-kather100k"
Expand Down Expand Up @@ -369,48 +401,6 @@ def test_patch_pred_zarr_store(track_tmp_path: pytest.TempPathFactory) -> None:
)
assert Path.exists(out), "Zarr output file does not exist"

eng = TestEngineABC(model="alexnet-kather100k")
with pytest.raises(
ValueError,
match=r".*Patch output must contain coordinates.",
):
_ = eng.run(
images=np.zeros((10, 224, 224, 3), dtype=np.uint8),
labels=list(range(10)),
device=device,
save_dir=save_dir,
overwrite=True,
output_type="AnnotationStore",
)

with pytest.raises(
ValueError,
match=r".*Patch output must contain coordinates.",
):
_ = eng.run(
images=np.zeros((10, 224, 224, 3), dtype=np.uint8),
labels=list(range(10)),
device=device,
save_dir=save_dir,
overwrite=True,
output_type="AnnotationStore",
class_dict={0: "class0", 1: "class1"},
)

with pytest.raises(
ValueError,
match=r".*Patch output must contain coordinates.",
):
_ = eng.run(
images=np.zeros((10, 224, 224, 3), dtype=np.uint8),
labels=list(range(10)),
device=device,
save_dir=save_dir,
overwrite=True,
output_type="AnnotationStore",
scale_factor=(2.0, 2.0),
)


def test_get_dataloader(sample_svs: Path) -> None:
"""Test the get_dataloader function."""
Expand Down
100 changes: 99 additions & 1 deletion tests/engines/test_ioconfig.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
"""Tests for IOconfig."""

import numpy as np
import pytest

from tiatoolbox.models import ModelIOConfigABC
from tiatoolbox.models import IOSegmentorConfig, ModelIOConfigABC


def test_validation_error_io_config() -> None:
Expand All @@ -21,3 +22,100 @@ def test_validation_error_io_config() -> None:
input_resolutions=[{"units": "level", "resolution": 1.0}],
patch_input_shape=(224, 224),
)


def test_scale_to_highest_mpp() -> None:
"""Mpp → min(old_vals) / old_vals."""
resolutions = [
{"units": "mpp", "resolution": 0.25},
{"units": "mpp", "resolution": 0.5},
]
result = ModelIOConfigABC.scale_to_highest(resolutions, units="mpp")

expected = np.array([1.0, 0.5]) # 0.25 / [0.25, 0.5]
np.testing.assert_allclose(result, expected)


def test_scale_to_highest_mpp_reversed_order() -> None:
"""Ensure order is preserved even when resolutions are reversed."""
resolutions = [
{"units": "mpp", "resolution": 0.5},
{"units": "mpp", "resolution": 0.25},
]
result = ModelIOConfigABC.scale_to_highest(resolutions, units="mpp")

expected = np.array([0.5, 1.0]) # 0.25 / [0.5, 0.25]
np.testing.assert_allclose(result, expected)


def test_scale_to_highest_baseline() -> None:
"""Baseline → identity."""
resolutions = [
{"units": "baseline", "resolution": 2.0},
{"units": "baseline", "resolution": 4.0},
]
result = ModelIOConfigABC.scale_to_highest(resolutions, units="baseline")

expected = [2.0, 4.0]
assert result == expected


def test_scale_to_highest_power() -> None:
"""Power → old_vals / max(old_vals)."""
resolutions = [
{"units": "power", "resolution": 10},
{"units": "power", "resolution": 5},
]
result = ModelIOConfigABC.scale_to_highest(resolutions, units="power")

expected = np.array([1.0, 0.5]) # [10, 5] / 10
np.testing.assert_allclose(result, expected)


def test_scale_to_highest_invalid_units() -> None:
"""Test ModelIOConfigABC for unknown units."""
resolutions = [{"units": "mpp", "resolution": 1.0}]
with pytest.raises(ValueError, match="Unknown units"):
ModelIOConfigABC.scale_to_highest(resolutions, units="unknown")


def test_modelio_to_baseline_without_save_resolution() -> None:
"""Test ModelIOConfigABC when save_resolution is None.

Ensure ModelIOConfigABC.to_baseline does NOT add or convert
save_resolution when it is None.

"""
cfg = ModelIOConfigABC(
input_resolutions=[{"units": "mpp", "resolution": 0.5}],
output_resolutions=[{"units": "mpp", "resolution": 1.0}],
patch_input_shape=(224, 224),
stride_shape=(224, 224),
)

new_cfg = cfg.to_baseline()

# save_resolution should not appear in the new config
assert not hasattr(new_cfg, "save_resolution") or new_cfg.save_resolution is None


def test_ios_to_baseline_without_save_resolution() -> None:
"""Test IOSegmentorConfig when save_resolution is None.

Ensure IOSegmentorConfig.to_baseline leaves save_resolution=None
when no save_resolution is provided.

"""
cfg = IOSegmentorConfig(
input_resolutions=[{"units": "mpp", "resolution": 0.5}],
output_resolutions=[{"units": "mpp", "resolution": 1.0}],
patch_input_shape=(224, 224),
patch_output_shape=(112, 112),
stride_shape=(224, 224),
save_resolution=None,
)

new_cfg = cfg.to_baseline()

# save_resolution should remain None after conversion
assert new_cfg.save_resolution is None
Loading