diff --git a/.github/workflows/build-test-package.yml b/.github/workflows/build-test-package.yml index a173779..53c48e9 100644 --- a/.github/workflows/build-test-package.yml +++ b/.github/workflows/build-test-package.yml @@ -12,7 +12,7 @@ jobs: include: - flake8-python-git-tag: "" - - itk-python-git-tag: "" + - pooch-python-git-tag: "" - pytest-python-git-tag: "" steps: @@ -36,7 +36,7 @@ jobs: sudo apt update sudo apt install openslide-tools python3-openslide python -m pip install --upgrade pip setuptools wheel - pip install 'flake8${{ matrix.flake8-python-git-tag }}' 'pytest${{ matrix.pytest-python-git-tag }}' 'itk${{ matrix.itk-python-git-tag }}' 'tensorflow' + pip install 'flake8${{ matrix.flake8-python-git-tag }}' 'pooch${{ matrix.pooch-python-git-tag }}' 'pytest${{ matrix.pytest-python-git-tag }}' pip install 'large-image[bioformats,ometiff,openjpeg,openslide,tiff]' 'scikit_image' --find-links https://girder.github.io/large_image_wheels - name: Install histomics_stream diff --git a/histomics_stream/configure.py b/histomics_stream/configure.py index 220a20b..e6fe138 100644 --- a/histomics_stream/configure.py +++ b/histomics_stream/configure.py @@ -27,7 +27,7 @@ import numpy as np import random import re -import scipy +import scipy.interpolate class _TilesByCommon: diff --git a/test/test_find_itk.py b/test/test_find_imports.py similarity index 75% rename from test/test_find_itk.py rename to test/test_find_imports.py index c05e8eb..56b6594 100644 --- a/test/test_find_itk.py +++ b/test/test_find_imports.py @@ -19,12 +19,19 @@ # ========================================================================= -def test_itk_can_be_found(): - """Purpose: Test to check that ITK can be found""" +def test_imports_can_be_found(): + """Purpose: Test to check that each import can be found""" # Import succeeds + import imagecodecs import itk + import numcodecs + import numpy + import scipy.interpolate + import tensorflow + import torch + import zarr if __name__ == "__main__": - test_itk_can_be_found() + test_imports_can_be_found() diff --git a/test/test_mask.py b/test/test_mask.py new file mode 100644 index 0000000..0a4d3e7 --- /dev/null +++ b/test/test_mask.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python3 + +# ========================================================================= +# +# Copyright NumFOCUS +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0.txt +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ========================================================================= + + +def test_mask_threshold(): + import histomics_stream as hs + import os + import pooch + + wsi_path = pooch.retrieve( + fname="TCGA-AN-A0G0-01Z-00-DX1.svs", + url=( + "https://drive.google.com/uc" + "?export=download" + "&id=19agE_0cWY582szhOVxp9h3kozRfB4CvV" + "&confirm=t" + "&uuid=6f2d51e7-9366-4e98-abc7-4f77427dd02c" + "&at=ALgDtswlqJJw1KU7P3Z1tZNcE01I:1679111148632" + ), + known_hash="d046f952759ff6987374786768fc588740eef1e54e4e295a684f3bd356c8528f", + path=str(pooch.os_cache("pooch")) + os.sep + "wsi", + ) + print(f"Have {wsi_path}") + + # download binary mask image + mask_path = pooch.retrieve( + fname="TCGA-AN-A0G0-01Z-00-DX1.mask.png", + url=( + "https://drive.google.com/uc" + "?export=download" + "&id=17GOOHbL8Bo3933rdIui82akr7stbRfta" + ), + known_hash="bb657ead9fd3b8284db6ecc1ca8a1efa57a0e9fd73d2ea63ce6053fbd3d65171", + path=str(pooch.os_cache("pooch")) + os.sep + "wsi", + ) + print(f"Have {mask_path}") + + my_study = dict( + version="version-1", + tile_width=5471, + tile_height=5743, + overlap_width=127, + overlap_height=101, + slides=dict( + Slide_0=dict( + filename=wsi_path, + slide_name=os.path.splitext(os.path.split(wsi_path)[1])[0], + slide_group="test_mask_threshold", + chunk_width=31, + chunk_height=37, + ) + ), + ) + find_slide_resolution = hs.configure.FindResolutionForSlide( + my_study, target_magnification=20, magnification_source="native" + ) + for slide in my_study["slides"].values(): + find_slide_resolution(slide) + + tiler_thresholds = (0.00, 0.20, 0.50, 0.80, 1.00) + tilers = [ + hs.configure.TilesByGridAndMask( + my_study, mask_filename=mask_path, mask_threshold=threshold + ) + for threshold in tiler_thresholds + ] + + def run_tiler(study, tiler): + for slide in study["slides"].values(): + tiler(slide) + return tiler.get_tiles(my_study) + + found_tiles = [run_tiler(my_study, tiler) for tiler in tilers] + + # print(f" expected_tiles = {repr(found_tiles)}") + expected_tiles = [ + [ + ( + wsi_path, + [(0, 10688), (0, 16032), (0, 21376)] + + [(5642, 5344), (5642, 10688), (5642, 16032), (5642, 21376)] + + [(11284, 5344), (11284, 10688), (11284, 16032), (11284, 21376)], + ) + ], + [ + ( + wsi_path, + [(0, 16032), (0, 21376)] + + [(5642, 5344), (5642, 10688), (5642, 16032), (5642, 21376)] + + [(11284, 5344), (11284, 10688), (11284, 16032), (11284, 21376)], + ) + ], + [ + ( + wsi_path, + [(0, 16032), (0, 21376)] + + [(5642, 10688), (5642, 16032), (5642, 21376)] + + [(11284, 10688), (11284, 16032)], + ) + ], + [(wsi_path, [(5642, 10688), (5642, 16032), (11284, 10688), (11284, 16032)])], + [(wsi_path, [(5642, 16032), (11284, 16032)])], + ] + + for i in range(len(found_tiles) - 1): + assert set(found_tiles[i + 1][0][1]).issubset(set(found_tiles[i + 1][0][1])) + for i in range(len(found_tiles)): + assert found_tiles[i] == expected_tiles[i] + print("Test succeeded") + + +if __name__ == "__main__": + test_mask_threshold()