Skip to content

Commit 64f3537

Browse files
authored
Feature slide info (#1)
DEV: Add feature to collect slide meta data Merge pull request #1 from develop Add Feature slide-info - Add WSIReader class to read whole slide images. Currently this class is using openslide and therefore can only read file formats supported by openslide - Add slide_info function which returns slide meta information - Add TIAMultiProcess decorator to run functions using multiple cores. - Add misc to write miscellaneous small functions repeatedly required for use in the repo.
1 parent c52d43d commit 64f3537

21 files changed

+590
-42
lines changed

.travis.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ python:
55
- 3.8
66
- 3.7
77
- 3.6
8-
- 3.5
8+
9+
before_install:
10+
- sudo apt-get -y install openslide-tools
911

1012
# Command to install dependencies, e.g. pip install -r requirements.txt --use-mirrors
1113
install: pip install -U tox-travis

README.rst

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,56 @@
1+
.. raw:: html
2+
3+
<p align="center">
4+
<img width="450" height="200" src=https://warwick.ac.uk/fac/sci/dcs/research/tia/tiatoolbox/files/tialab_logo.png>
5+
</p>
6+
17
===========
28
TIA Toolbox
39
===========
410

11+
Computational Pathology Toolbox developed by TIA Lab
12+
13+
Please try
14+
15+
::
16+
17+
python -m tiatoolbox -h
18+
19+
Getting Started
20+
===============
521

22+
First, install OpenSlide `here <https://openslide.org/download/>`__. Then, create and
23+
activate the conda environment:
624

25+
pip
26+
----
727

28+
::
829

30+
pip install -r requirements_dev.txt
931

10-
Computational pathology toolbox developed by TIA Lab.
32+
conda
33+
-----
34+
::
1135

36+
conda env create --name tiatoolbox --file requirements.conda.yml
37+
conda activate tiatoolbox
1238

39+
tiatoolbox --help
40+
=======================
1341

14-
Features
15-
--------
42+
::
1643

17-
* TODO
44+
usage: tiatoolbox [-h] [--version] [--verbose VERBOSE]
45+
{slide_info}
46+
...
1847

19-
Credits
20-
-------
48+
positional arguments:
49+
{slide_info}
50+
slide_info usage: python -m tiatoolbox slide_info -h
2151

22-
This package was created with Cookiecutter_ and the `audreyr/cookiecutter-pypackage`_ project template.
52+
optional arguments:
53+
-h, --help show this help message and exit
54+
--version show program`s version number and exit
55+
--verbose VERBOSE
2356

24-
.. _Cookiecutter: https://github.com/audreyr/cookiecutter
25-
.. _`audreyr/cookiecutter-pypackage`: https://github.com/audreyr/cookiecutter-pypackage

docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232

3333
# Add any Sphinx extension module names here, as strings. They can be
3434
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
35-
extensions = ["sphinx.ext.autodoc", "sphinx.ext.viewcode"]
35+
extensions = ["sphinx.ext.autodoc", "sphinx.ext.viewcode", "sphinx.ext.napoleon"]
3636

3737
# Add any paths that contain templates here, relative to this directory.
3838
templates_path = ["_templates"]

docs/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Welcome to TIA Toolbox's documentation!
2-
======================================
2+
=======================================
33

44
.. toctree::
55
:maxdepth: 2

docs/tialab_logo.png

53.8 KB
Loading

docs/usage.rst

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,47 @@ Usage
55
To use TIA Toolbox in a project::
66

77
import tiatoolbox
8+
9+
10+
----------
11+
Dataloader
12+
----------
13+
.. automodule:: tiatoolbox.dataloader
14+
15+
^^^^^^^^^^^^^^^^^^^^
16+
dataloader.wsireader
17+
^^^^^^^^^^^^^^^^^^^^
18+
19+
.. automodule:: tiatoolbox.dataloader.wsireader
20+
:members: WSIReader
21+
:special-members: __init__
22+
23+
^^^^^^^^^^^^^^^^^^^^^
24+
dataloader.slide_info
25+
^^^^^^^^^^^^^^^^^^^^^
26+
27+
.. automodule:: tiatoolbox.dataloader.slide_info
28+
:members: slide_info
29+
30+
----------
31+
Decorators
32+
----------
33+
.. automodule:: tiatoolbox.decorators
34+
35+
^^^^^^^^^^^^^^^^^^^^
36+
decorators.multiproc
37+
^^^^^^^^^^^^^^^^^^^^
38+
.. automodule:: tiatoolbox.decorators.multiproc
39+
:members: TIAMultiProcess
40+
:special-members: __init__, __call__
41+
42+
------
43+
Utils
44+
------
45+
.. automodule:: tiatoolbox.utils
46+
47+
^^^^^^^^^^
48+
utils.misc
49+
^^^^^^^^^^
50+
.. automodule:: tiatoolbox.utils.misc
51+
:members: save_yaml, split_path_name_ext, grab_files_from_dir

requirements.conda.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: tiatoolbox
2+
channels:
3+
- conda
4+
- conda-forge
5+
- defaults
6+
dependencies:
7+
- python=3.6
8+
- setuptools==45.1.0
9+
- Click==7.0
10+
- cython=0.29.15
11+
- h5py=2.8.0
12+
- matplotlib-base=3.1.3
13+
- numpy=1.18.1
14+
- opencv=4.2
15+
- pillow=7.0.0
16+
- pip=20.0.2
17+
- pyyaml=5.3.1
18+
- requests=2.23.0
19+
- pathos==0.2.5
20+
- pip:
21+
- openslide-python==1.1.1
22+

requirements_dev.txt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
pip==19.2.3
1+
pip==20.0.2
22
bump2version==0.5.11
33
wheel==0.33.6
44
watchdog==0.9.0
@@ -8,6 +8,10 @@ coverage==5.1
88
Sphinx==1.8.5
99
twine==1.14.0
1010
Click==7.0
11-
pytest==4.6.5
12-
pytest-runner==5.1
11+
setuptools==45.1.0
12+
pytest==5.4.2
13+
pytest-runner==5.2
14+
opencv-python==4.2.0.34
15+
pathos==0.2.5
16+
openslide-python==1.1.1
1317
pytest-cov==2.9.0

setup.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,18 @@
2525
setup(
2626
author="TIA Lab",
2727
author_email="[email protected]",
28-
python_requires=">=3.5",
28+
python_requires=">=3.6",
2929
classifiers=[
3030
"Development Status :: 2 - Pre-Alpha",
3131
"Intended Audience :: Developers",
3232
"Natural Language :: English",
3333
"Programming Language :: Python :: 3",
34-
"Programming Language :: Python :: 3.5",
3534
"Programming Language :: Python :: 3.6",
3635
"Programming Language :: Python :: 3.7",
3736
"Programming Language :: Python :: 3.8",
3837
],
3938
description="Computational pathology toolbox developed by TIA Lab.",
40-
entry_points={"console_scripts": ["tiatoolbox=tiatoolbox.cli:main",],},
39+
entry_points={"console_scripts": ["tiatoolbox=tiatoolbox.cli:main", ], },
4140
install_requires=requirements,
4241
long_description=readme + "\n\n" + history,
4342
include_package_data=True,

tests/test_tiatoolbox.py

Lines changed: 88 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,108 @@
11
#!/usr/bin/env python
22

33
"""Tests for `tiatoolbox` package."""
4-
54
import pytest
65

7-
from click.testing import CliRunner
8-
9-
from tiatoolbox import tiatoolbox
6+
from tiatoolbox.dataloader.slide_info import slide_info
7+
from tiatoolbox import utils
108
from tiatoolbox import cli
9+
from tiatoolbox import __version__
10+
11+
from click.testing import CliRunner
12+
import requests
13+
import os
14+
import pathlib
1115

1216

1317
@pytest.fixture
14-
def response():
15-
"""Sample pytest fixture.
18+
def _response_ndpi(request):
19+
"""
20+
Sample pytest fixture for ndpi images
21+
Download ndpi image for pytest
22+
"""
23+
ndpi_file_path = pathlib.Path(__file__).parent.joinpath("CMU-1.ndpi")
24+
if not pathlib.Path.is_file(ndpi_file_path):
25+
r = requests.get(
26+
"http://openslide.cs.cmu.edu/download/openslide-testdata"
27+
"/Hamamatsu/CMU-1.ndpi"
28+
)
29+
with open(ndpi_file_path, "wb") as f:
30+
f.write(r.content)
31+
32+
def close_ndpi():
33+
if pathlib.Path.is_file(ndpi_file_path):
34+
os.remove(str(ndpi_file_path))
35+
36+
request.addfinalizer(close_ndpi)
37+
return _response_ndpi
1638

17-
See more at: http://doc.pytest.org/en/latest/fixture.html
39+
40+
@pytest.fixture
41+
def _response_svs(request):
1842
"""
19-
# import requests
20-
# return requests.get('https://github.com/audreyr/cookiecutter-pypackage')
43+
Sample pytest fixture for svs images
44+
Download ndpi image for pytest
45+
"""
46+
svs_file_path = pathlib.Path(__file__).parent.joinpath("CMU-1.svs")
47+
if not pathlib.Path.is_file(svs_file_path):
48+
r = requests.get(
49+
"http://openslide.cs.cmu.edu/download/openslide-testdata"
50+
"/Hamamatsu/CMU-1.ndpi"
51+
)
52+
with open(svs_file_path, "wb") as f:
53+
f.write(r.content)
54+
55+
def close_ndpi():
56+
if pathlib.Path.is_file(svs_file_path):
57+
os.remove(str(svs_file_path))
58+
59+
request.addfinalizer(close_ndpi)
60+
return _response_svs
2161

2262

23-
def test_content(response):
24-
"""Sample pytest test function with the pytest fixture as an argument."""
25-
# from bs4 import BeautifulSoup
26-
# assert 'GitHub' in BeautifulSoup(response.content).title.string
63+
def test_slide_info(_response_ndpi, _response_svs):
64+
"""pytest for slide_info as a python function"""
65+
file_types = ("*.ndpi", "*.svs", "*.mrxs")
66+
files_all = utils.misc.grab_files_from_dir(
67+
input_path=str(pathlib.Path(r".")), file_types=file_types,
68+
)
69+
slide_params = slide_info(input_path=files_all, workers=2)
2770

71+
for slide_param in slide_params:
72+
utils.misc.save_yaml(slide_param, slide_param["file_name"] + ".yaml")
2873

29-
def test_command_line_interface():
30-
"""Test the CLI."""
74+
75+
def test_command_line_help_interface():
76+
"""Test the CLI help"""
3177
runner = CliRunner()
3278
result = runner.invoke(cli.main)
3379
assert result.exit_code == 0
34-
assert "tiatoolbox.cli.main" in result.output
3580
help_result = runner.invoke(cli.main, ["--help"])
3681
assert help_result.exit_code == 0
37-
assert "--help Show this message and exit." in help_result.output
82+
assert help_result.output == result.output
83+
84+
85+
def test_command_line_version():
86+
"""pytest for version check"""
87+
runner = CliRunner()
88+
version_result = runner.invoke(cli.main, ["-V"])
89+
assert __version__ in version_result.output
90+
91+
92+
def test_command_line_slide_info(_response_ndpi, _response_svs):
93+
"""Test the Slide information CLI."""
94+
runner = CliRunner()
95+
slide_info_result = runner.invoke(
96+
cli.main,
97+
[
98+
"slide-info",
99+
"--wsi_input",
100+
".",
101+
"--file_types",
102+
'"*.ndpi, *.svs"',
103+
"--workers",
104+
"2",
105+
],
106+
)
107+
108+
assert slide_info_result.exit_code == 0

0 commit comments

Comments
 (0)