From 813fc1c0f4764ae827cc9d71d101a00bbff4a102 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ho=CC=88rst?= Date: Fri, 12 Jan 2024 12:40:25 +0100 Subject: [PATCH 1/3] First setp of making a pypi package --- LICENSE.md | 1 + README.md | 3 + environment.yaml | 30 +-------- {pathopatcher => pathopatch}/__init__.py | 0 .../annotation_conversion.py | 0 .../base_ml/__init__.py | 0 .../base_ml/base_cli.py | 0 {pathopatcher => pathopatch}/cli.py | 6 +- .../config/__init__.py | 0 {pathopatcher => pathopatch}/config/config.py | 0 {pathopatcher => pathopatch}/data/__init__.py | 0 .../data/tissue_detector.pt | Bin .../macenko_vector_generation.py | 4 +- .../patch_extraction/__init__.py | 0 .../patch_extraction/cucim_deepzoom.py | 0 .../patch_extraction/patch_extraction.py | 18 +++--- .../patch_extraction/process_batch.py | 8 +-- .../patch_extraction/storage.py | 0 pathopatch/test_cli.py | 36 +++++++++++ .../utils/__init__.py | 0 .../utils/exceptions.py | 0 .../utils/file_handling.py | 0 {pathopatcher => pathopatch}/utils/logger.py | 2 +- {pathopatcher => pathopatch}/utils/masking.py | 2 +- .../utils/patch_dataset.py | 0 .../utils/patch_util.py | 8 +-- .../utils/plotting.py | 4 +- {pathopatcher => pathopatch}/utils/tools.py | 2 +- .../wsi_extraction.py | 16 +++-- requirements.txt | 21 ++++++ requirements_develop.txt | 27 ++++++++ setup.py | 60 ++++++++++++++++++ tests/test_cli/test_cli.py | 2 +- .../test_annotations_filtering.py | 8 +-- tests/test_core_modules/test_baseline.py | 8 +-- tests/test_core_modules/test_complex_setup.py | 8 +-- tests/test_core_modules/test_downsample.py | 8 +-- tests/test_core_modules/test_roi.py | 8 +-- tests/test_core_modules/test_roi_context.py | 8 +-- .../test_target_magnification.py | 8 +-- tests/test_core_modules/test_target_mpp.py | 8 +-- .../test_target_mpp_macenko.py | 8 +-- .../test_macenko_loading.py | 4 +- .../test_macenko_saving.py | 4 +- tests/test_utils/test_csv_loading.py | 2 +- tests/test_utils/test_mask_rgb.py | 2 +- 46 files changed, 228 insertions(+), 106 deletions(-) create mode 100644 LICENSE.md rename {pathopatcher => pathopatch}/__init__.py (100%) rename {pathopatcher => pathopatch}/annotation_conversion.py (100%) rename {pathopatcher => pathopatch}/base_ml/__init__.py (100%) rename {pathopatcher => pathopatch}/base_ml/base_cli.py (100%) rename {pathopatcher => pathopatch}/cli.py (99%) rename {pathopatcher => pathopatch}/config/__init__.py (100%) rename {pathopatcher => pathopatch}/config/config.py (100%) rename {pathopatcher => pathopatch}/data/__init__.py (100%) rename {pathopatcher => pathopatch}/data/tissue_detector.pt (100%) rename pathopatcher/macenko.py => pathopatch/macenko_vector_generation.py (88%) rename {pathopatcher => pathopatch}/patch_extraction/__init__.py (100%) rename {pathopatcher => pathopatch}/patch_extraction/cucim_deepzoom.py (100%) rename {pathopatcher => pathopatch}/patch_extraction/patch_extraction.py (99%) rename {pathopatcher => pathopatch}/patch_extraction/process_batch.py (97%) rename {pathopatcher => pathopatch}/patch_extraction/storage.py (100%) create mode 100644 pathopatch/test_cli.py rename {pathopatcher => pathopatch}/utils/__init__.py (100%) rename {pathopatcher => pathopatch}/utils/exceptions.py (100%) rename {pathopatcher => pathopatch}/utils/file_handling.py (100%) rename {pathopatcher => pathopatch}/utils/logger.py (99%) rename {pathopatcher => pathopatch}/utils/masking.py (99%) rename {pathopatcher => pathopatch}/utils/patch_dataset.py (100%) rename {pathopatcher => pathopatch}/utils/patch_util.py (99%) rename {pathopatcher => pathopatch}/utils/plotting.py (98%) rename {pathopatcher => pathopatch}/utils/tools.py (99%) rename pathopatcher/main_extraction.py => pathopatch/wsi_extraction.py (64%) create mode 100644 requirements.txt create mode 100644 requirements_develop.txt create mode 100644 setup.py diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..63c3212 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1 @@ +

PathoPatcher by Fabian Hörst, University Hospital Essen, is licensed under CC BY-NC-SA 4.0

\ No newline at end of file diff --git a/README.md b/README.md index 39a19c1..9e75532 100644 --- a/README.md +++ b/README.md @@ -275,3 +275,6 @@ TBD ## Citation TBD + +## License +

PathoPatcher by Fabian Hörst, University Hospital Essen, is licensed under CC BY-NC-SA 4.0

\ No newline at end of file diff --git a/environment.yaml b/environment.yaml index 2795208..1f302c8 100644 --- a/environment.yaml +++ b/environment.yaml @@ -11,52 +11,24 @@ dependencies: - Pillow==9.5.0 - PyYAML==6.0 - Shapely==1.8.5.post1 - - SimpleITK==2.2.1 - - albumentations==1.3.0 - black==23.1.0 - - csbdeep==0.7.4 - colorama==0.4.6 - - einops==0.6.1 - flake8-html==0.4.3 - flake8==6.0.0 - - future==0.18.2 - genbadge==1.1.0 - geojson==3.0.0 - - h5py==3.9.0 - histolab==0.6.0 - - imageio==2.31.1 - - ipython-genutils==0.2.0 - - jupyterlab==4.0.2 - - kaleido==0.2.1 - - keras==2.12.0 - - keras==2.12.0 - - mako==1.2.4 - matplotlib==3.7.1 - natsort==8.4.0 - numpy>1.22,<1.24 - opencv_python_headless==4.5.4.58 - openslide_python==1.2.0 - - pandarallel==1.6.5 - pandas==1.5.3 - pre-commit==3.0.3 - pydantic==1.10.4 - - pyjwt==2.6.0 - pytest==7.4.4 - pytest-sugar==0.9.7 - rasterio==1.3.5.post1 - - schema==0.7.5 - scikit-image==0.19.3 - - scikit-learn==1.2.1 - - scikit-survival==0.21.0 - - scipy>1.5.0,<=1.8.2 - - seaborn==0.12.2 - - sqlalchemy==2.0.17 - - stardist==0.8.5 - - tabulate==0.9.0 - - tensorflow==2.12.0 - - torchinfo==1.8.0 - - torchmetrics==0.11.4 - torchvision==0.16.2 - - tqdm==4.65.0 - - ujson==5.8.0 - - wandb==0.15.4 + - tqdm==4.65.0 \ No newline at end of file diff --git a/pathopatcher/__init__.py b/pathopatch/__init__.py similarity index 100% rename from pathopatcher/__init__.py rename to pathopatch/__init__.py diff --git a/pathopatcher/annotation_conversion.py b/pathopatch/annotation_conversion.py similarity index 100% rename from pathopatcher/annotation_conversion.py rename to pathopatch/annotation_conversion.py diff --git a/pathopatcher/base_ml/__init__.py b/pathopatch/base_ml/__init__.py similarity index 100% rename from pathopatcher/base_ml/__init__.py rename to pathopatch/base_ml/__init__.py diff --git a/pathopatcher/base_ml/base_cli.py b/pathopatch/base_ml/base_cli.py similarity index 100% rename from pathopatcher/base_ml/base_cli.py rename to pathopatch/base_ml/base_cli.py diff --git a/pathopatcher/cli.py b/pathopatch/cli.py similarity index 99% rename from pathopatcher/cli.py rename to pathopatch/cli.py index 4251283..260951b 100644 --- a/pathopatcher/cli.py +++ b/pathopatch/cli.py @@ -16,9 +16,9 @@ import yaml from pydantic import BaseModel, validator -from pathopatcher.base_ml.base_cli import ABCParser -from pathopatcher.config.config import ANNOTATION_EXT, LOGGING_EXT, WSI_EXT -from pathopatcher.utils.logger import Logger +from pathopatch.base_ml.base_cli import ABCParser +from pathopatch.config.config import ANNOTATION_EXT, LOGGING_EXT, WSI_EXT +from pathopatch.utils.logger import Logger class PreProcessingYamlConfig(BaseModel): diff --git a/pathopatcher/config/__init__.py b/pathopatch/config/__init__.py similarity index 100% rename from pathopatcher/config/__init__.py rename to pathopatch/config/__init__.py diff --git a/pathopatcher/config/config.py b/pathopatch/config/config.py similarity index 100% rename from pathopatcher/config/config.py rename to pathopatch/config/config.py diff --git a/pathopatcher/data/__init__.py b/pathopatch/data/__init__.py similarity index 100% rename from pathopatcher/data/__init__.py rename to pathopatch/data/__init__.py diff --git a/pathopatcher/data/tissue_detector.pt b/pathopatch/data/tissue_detector.pt similarity index 100% rename from pathopatcher/data/tissue_detector.pt rename to pathopatch/data/tissue_detector.pt diff --git a/pathopatcher/macenko.py b/pathopatch/macenko_vector_generation.py similarity index 88% rename from pathopatcher/macenko.py rename to pathopatch/macenko_vector_generation.py index bd57495..a90c7f8 100644 --- a/pathopatcher/macenko.py +++ b/pathopatch/macenko_vector_generation.py @@ -15,8 +15,8 @@ parentdir = os.path.dirname(parentdir) sys.path.insert(0, parentdir) -from pathopatcher.cli import MacenkoParser -from pathopatcher.patch_extraction.patch_extraction import PreProcessor +from pathopatch.cli import MacenkoParser +from pathopatch.patch_extraction.patch_extraction import PreProcessor if __name__ == "__main__": configuration_parser = MacenkoParser() diff --git a/pathopatcher/patch_extraction/__init__.py b/pathopatch/patch_extraction/__init__.py similarity index 100% rename from pathopatcher/patch_extraction/__init__.py rename to pathopatch/patch_extraction/__init__.py diff --git a/pathopatcher/patch_extraction/cucim_deepzoom.py b/pathopatch/patch_extraction/cucim_deepzoom.py similarity index 100% rename from pathopatcher/patch_extraction/cucim_deepzoom.py rename to pathopatch/patch_extraction/cucim_deepzoom.py diff --git a/pathopatcher/patch_extraction/patch_extraction.py b/pathopatch/patch_extraction/patch_extraction.py similarity index 99% rename from pathopatcher/patch_extraction/patch_extraction.py rename to pathopatch/patch_extraction/patch_extraction.py index 4c6db06..8d6c811 100644 --- a/pathopatcher/patch_extraction/patch_extraction.py +++ b/pathopatch/patch_extraction/patch_extraction.py @@ -31,15 +31,15 @@ from shapely.geometry import Polygon from tqdm import tqdm -from pathopatcher import logger -from pathopatcher.cli import PreProcessingConfig -from pathopatcher.patch_extraction.storage import Storage -from pathopatcher.utils.exceptions import ( +from pathopatch import logger +from pathopatch.cli import PreProcessingConfig +from pathopatch.patch_extraction.storage import Storage +from pathopatch.utils.exceptions import ( UnalignedDataException, WrongParameterException, ) -from pathopatcher.utils.patch_dataset import load_tissue_detection_dl -from pathopatcher.utils.patch_util import ( +from pathopatch.utils.patch_dataset import load_tissue_detection_dl +from pathopatch.utils.patch_util import ( DeepZoomGeneratorOS, calculate_background_ratio, compute_interesting_patches, @@ -55,7 +55,7 @@ target_mag_to_downsample, target_mpp_to_downsample, ) -from pathopatcher.utils.tools import end_timer, module_exists, start_timer +from pathopatch.utils.tools import end_timer, module_exists, start_timer warnings.filterwarnings("ignore", category=DeprecationWarning) warnings.filterwarnings("ignore", category=UserWarning) @@ -414,7 +414,7 @@ def _set_hardware(self, hardware_selection: str = "cucim") -> None: logger.info("Using CuCIM") from cucim import CuImage - from pathopatcher.patch_extraction.cucim_deepzoom import ( + from pathopatch.patch_extraction.cucim_deepzoom import ( DeepZoomGeneratorCucim, ) @@ -458,7 +458,7 @@ def _set_tissue_detector(self) -> None: model = mobilenet_v3_small().to(device=self.detector_device) model.classifier[-1] = nn.Linear(1024, 4) checkpoint = torch.load( - "./pathopatcher/data/tissue_detector.pt", + "./pathopatch/data/tissue_detector.pt", # this causes errors map_location=self.detector_device, ) model.load_state_dict(checkpoint["model_state_dict"]) diff --git a/pathopatcher/patch_extraction/process_batch.py b/pathopatch/patch_extraction/process_batch.py similarity index 97% rename from pathopatcher/patch_extraction/process_batch.py rename to pathopatch/patch_extraction/process_batch.py index 0d37e5f..5a79d04 100644 --- a/pathopatcher/patch_extraction/process_batch.py +++ b/pathopatch/patch_extraction/process_batch.py @@ -15,7 +15,7 @@ from PIL import Image from shapely.geometry import Polygon -from pathopatcher.utils.patch_util import ( +from pathopatch.utils.patch_util import ( DeepZoomGeneratorOS, calculate_background_ratio, get_intersected_labels, @@ -24,9 +24,9 @@ patch_to_tile_size, standardize_brightness, ) -from pathopatcher.utils.tools import module_exists +from pathopatch.utils.tools import module_exists -from pathopatcher import logger +from pathopatch import logger def process_batch( @@ -107,7 +107,7 @@ def process_batch( if module_exists("cucim", error="ignore"): from cucim import CuImage - from pathopatcher.deepzoom.cucim_deepzoom import DeepZoomGeneratorCucim + from pathopatch.deepzoom.cucim_deepzoom import DeepZoomGeneratorCucim generator_module = DeepZoomGeneratorCucim image_loader = CuImage diff --git a/pathopatcher/patch_extraction/storage.py b/pathopatch/patch_extraction/storage.py similarity index 100% rename from pathopatcher/patch_extraction/storage.py rename to pathopatch/patch_extraction/storage.py diff --git a/pathopatch/test_cli.py b/pathopatch/test_cli.py new file mode 100644 index 0000000..eee1b5d --- /dev/null +++ b/pathopatch/test_cli.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# Geojson annotation preprocessing +# +# @ Fabian Hörst, fabian.hoerst@uk-essen.de +# Institute for Artifical Intelligence in Medicine, +# University Medicine Essen + +import os +import json +from tqdm import tqdm +import argparse +import uuid + +def main(): + parser = argparse.ArgumentParser( + description="Convert GeoJSON annotations (from QuPath) to JSON format." + ) + parser.add_argument( + "--input_folder", + type=str, + help="Path to the input folder containing GeoJSON files.", + ) + parser.add_argument( + "--output_folder", type=str, help="Path to the output folder for JSON files." + ) + parser.add_argument( + "--generate_tissue_outline", + action="store_true", + help="Generate tissue outline.", + ) + args = parser.parse_args() + print(args) + + +if __name__ == "__main__": + main() diff --git a/pathopatcher/utils/__init__.py b/pathopatch/utils/__init__.py similarity index 100% rename from pathopatcher/utils/__init__.py rename to pathopatch/utils/__init__.py diff --git a/pathopatcher/utils/exceptions.py b/pathopatch/utils/exceptions.py similarity index 100% rename from pathopatcher/utils/exceptions.py rename to pathopatch/utils/exceptions.py diff --git a/pathopatcher/utils/file_handling.py b/pathopatch/utils/file_handling.py similarity index 100% rename from pathopatcher/utils/file_handling.py rename to pathopatch/utils/file_handling.py diff --git a/pathopatcher/utils/logger.py b/pathopatch/utils/logger.py similarity index 99% rename from pathopatcher/utils/logger.py rename to pathopatch/utils/logger.py index 1eab953..a7a0a3d 100644 --- a/pathopatcher/utils/logger.py +++ b/pathopatch/utils/logger.py @@ -14,7 +14,7 @@ import sys from colorama import init -from pathopatcher.config.config import COLOR_CODES_LOGGING +from pathopatch.config.config import COLOR_CODES_LOGGING init(autoreset=True) diff --git a/pathopatcher/utils/masking.py b/pathopatch/utils/masking.py similarity index 99% rename from pathopatcher/utils/masking.py rename to pathopatch/utils/masking.py index fe59c59..243f899 100644 --- a/pathopatcher/utils/masking.py +++ b/pathopatch/utils/masking.py @@ -22,7 +22,7 @@ from shapely.affinity import scale from shapely.geometry import Polygon -from pathopatcher import logger +from pathopatch import logger def generate_tissue_mask( diff --git a/pathopatcher/utils/patch_dataset.py b/pathopatch/utils/patch_dataset.py similarity index 100% rename from pathopatcher/utils/patch_dataset.py rename to pathopatch/utils/patch_dataset.py diff --git a/pathopatcher/utils/patch_util.py b/pathopatch/utils/patch_util.py similarity index 99% rename from pathopatcher/utils/patch_util.py rename to pathopatch/utils/patch_util.py index 33a9124..7b0497d 100644 --- a/pathopatcher/utils/patch_util.py +++ b/pathopatch/utils/patch_util.py @@ -24,13 +24,13 @@ from shapely.geometry import Polygon, shape from shapely.validation import make_valid -from pathopatcher import logger -from pathopatcher.utils.exceptions import WrongParameterException -from pathopatcher.utils.masking import ( +from pathopatch import logger +from pathopatch.utils.exceptions import WrongParameterException +from pathopatch.utils.masking import ( convert_polygons_to_mask, generate_tissue_mask, ) -from pathopatcher.utils.plotting import generate_polygon_overview +from pathopatch.utils.plotting import generate_polygon_overview def get_files_from_dir( diff --git a/pathopatcher/utils/plotting.py b/pathopatch/utils/plotting.py similarity index 98% rename from pathopatcher/utils/plotting.py rename to pathopatch/utils/plotting.py index 3e1ea08..9fedad3 100644 --- a/pathopatcher/utils/plotting.py +++ b/pathopatch/utils/plotting.py @@ -16,8 +16,8 @@ from rasterio.mask import mask as rasterio_mask from shapely.geometry import Polygon -from pathopatcher.config.config import COLOR_DEFINITIONS -from pathopatcher.utils.masking import get_filtered_polygons +from pathopatch.config.config import COLOR_DEFINITIONS +from pathopatch.utils.masking import get_filtered_polygons def generate_polygon_overview( diff --git a/pathopatcher/utils/tools.py b/pathopatch/utils/tools.py similarity index 99% rename from pathopatcher/utils/tools.py rename to pathopatch/utils/tools.py index 4738201..a4b2b2b 100644 --- a/pathopatcher/utils/tools.py +++ b/pathopatch/utils/tools.py @@ -13,7 +13,7 @@ from timeit import default_timer as timer from typing import Dict, List, Optional, Tuple, Union -from pathopatcher import logger +from pathopatch import logger # Helper timing functions diff --git a/pathopatcher/main_extraction.py b/pathopatch/wsi_extraction.py similarity index 64% rename from pathopatcher/main_extraction.py rename to pathopatch/wsi_extraction.py index cd68087..1bd0bc9 100644 --- a/pathopatcher/main_extraction.py +++ b/pathopatch/wsi_extraction.py @@ -1,3 +1,5 @@ +# !/usr/bin/env python + # -*- coding: utf-8 -*- # Main entry point for patch-preprocessing # @@ -8,19 +10,19 @@ import sys import os -project_root = os.path.dirname(os.path.abspath(__file__)) -sys.path.append(project_root) -project_root = os.path.dirname(os.path.abspath(project_root)) -sys.path.append(project_root) +# project_root = os.path.dirname(os.path.abspath(__file__)) +# sys.path.append(project_root) +# project_root = os.path.dirname(os.path.abspath(project_root)) +# sys.path.append(project_root) import logging logger = logging.getLogger() logger.addHandler(logging.NullHandler()) -from pathopatcher.cli import PreProcessingParser -from pathopatcher.patch_extraction.patch_extraction import PreProcessor -from pathopatcher.utils.tools import close_logger +from pathopatch.cli import PreProcessingParser +from pathopatch.patch_extraction.patch_extraction import PreProcessor +from pathopatch.utils.tools import close_logger if __name__ == "__main__": configuration_parser = PreProcessingParser() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..7d07738 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,21 @@ +Pillow>=9.5.0 +PyYAML +Shapely==1.8.5.post1 +colorama +future +geojson==3.0.0 +histolab==0.6.0 +matplotlib +natsort +numpy>1.22,<1.24 +opencv_python_headless +openslide_python +pandas +pydantic==1.10.4 +rasterio==1.3.5.post1 +requests +scikit-image +setuptools<=65.6.3 +tqdm +torchvision +torch \ No newline at end of file diff --git a/requirements_develop.txt b/requirements_develop.txt new file mode 100644 index 0000000..6b8f8b6 --- /dev/null +++ b/requirements_develop.txt @@ -0,0 +1,27 @@ +Pillow>=9.5.0 +PyYAML +Shapely==1.8.5.post1 +black +colorama +flake8 +flake8-html +genbadge +geojson==3.0.0 +histolab==0.6.0 +matplotlib +natsort +numpy>1.22,<1.24 +opencv_python_headless +openslide_python +pandas +pre-commit +pydantic==1.10.4 +pytest +pytest-sugar +rasterio==1.3.5.post1 +requests +scikit-image +setuptools<=65.6.3 +tqdm +torchvision +torch \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..b2472dc --- /dev/null +++ b/setup.py @@ -0,0 +1,60 @@ +from setuptools import setup + +VERSION = '2024.0.1a' +DESCRIPTION = 'PathoPatch - Accelerating Artificial Intelligence Based Whole Slide Image Analysis with an Optimized Preprocessing Pipeline' +with open("README.md", "r") as fh: + LONG_DESCRIPTION = fh.read() + +# Setting up +setup( + # the name must match the folder name 'verysimplemodule' + name="pathopatch", + version=VERSION, + author="Fabian Hörst", + author_email="fabian.hoerst@uk-essen.de", + description=DESCRIPTION, + long_description=LONG_DESCRIPTION, + url="https://github.com/TIO-IKIM/PathoPatcher", + long_description_content_type="text/markdown", + packages=["pathopatch"], + python_requires=">=3.9", + install_requires=[ + "Pillow>=9.5.0", + "PyYAML", + "Shapely==1.8.5.post1", + "colorama", + "future", + "geojson==3.0.0", + "histolab==0.6.0", + "matplotlib", + "natsort", + "numpy>1.22,<1.24", + "opencv_python_headless", + "openslide_python", + "pandas", + "pydantic==1.10.4", + "rasterio==1.3.5.post1", + "requests", + "scikit-image", + "setuptools<=65.6.3", + "tqdm", + "torchvision", + "torch" + ], + scripts=[ + "pathopatch/wsi_extraction.py", + "pathopatch/test_cli.py", + "pathopatch/annotation_conversion.py", + "pathopatch/macenko_vector_generation.py" + ], + keywords=["python", "pathopatch"], + classifiers= [ + "Development Status :: 3 - Alpha", + "Intended Audience :: Education", + "Topic :: Scientific/Engineering :: Artificial Intelligence", + "Programming Language :: Python :: 3", + "Operating System :: MacOS :: MacOS X", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX :: Other" + ] +) \ No newline at end of file diff --git a/tests/test_cli/test_cli.py b/tests/test_cli/test_cli.py index 064d7ab..13d3470 100644 --- a/tests/test_cli/test_cli.py +++ b/tests/test_cli/test_cli.py @@ -11,7 +11,7 @@ parentdir = os.path.dirname(currentdir) sys.path.insert(0, parentdir) -from pathopatcher.cli import ( +from pathopatch.cli import ( PreProcessingConfig, PreProcessingYamlConfig, ) diff --git a/tests/test_core_modules/test_annotations_filtering.py b/tests/test_core_modules/test_annotations_filtering.py index 92255d2..0e1ca43 100644 --- a/tests/test_core_modules/test_annotations_filtering.py +++ b/tests/test_core_modules/test_annotations_filtering.py @@ -9,10 +9,10 @@ from numpy.testing import assert_almost_equal from PIL import Image -from pathopatcher.cli import PreProcessingConfig, PreProcessingYamlConfig -from pathopatcher.patch_extraction.patch_extraction import PreProcessor -from pathopatcher.utils.logger import Logger -from pathopatcher.utils.tools import close_logger +from pathopatch.cli import PreProcessingConfig, PreProcessingYamlConfig +from pathopatch.patch_extraction.patch_extraction import PreProcessor +from pathopatch.utils.logger import Logger +from pathopatch.utils.tools import close_logger from test_database.download import check_test_database diff --git a/tests/test_core_modules/test_baseline.py b/tests/test_core_modules/test_baseline.py index 9e365ad..b7ea593 100644 --- a/tests/test_core_modules/test_baseline.py +++ b/tests/test_core_modules/test_baseline.py @@ -9,10 +9,10 @@ from numpy.testing import assert_almost_equal from PIL import Image -from pathopatcher.cli import PreProcessingConfig, PreProcessingYamlConfig -from pathopatcher.patch_extraction.patch_extraction import PreProcessor -from pathopatcher.utils.logger import Logger -from pathopatcher.utils.tools import close_logger +from pathopatch.cli import PreProcessingConfig, PreProcessingYamlConfig +from pathopatch.patch_extraction.patch_extraction import PreProcessor +from pathopatch.utils.logger import Logger +from pathopatch.utils.tools import close_logger from test_database.download import check_test_database diff --git a/tests/test_core_modules/test_complex_setup.py b/tests/test_core_modules/test_complex_setup.py index cea0a72..4595e35 100644 --- a/tests/test_core_modules/test_complex_setup.py +++ b/tests/test_core_modules/test_complex_setup.py @@ -9,10 +9,10 @@ from numpy.testing import assert_array_equal from PIL import Image -from pathopatcher.cli import PreProcessingConfig, PreProcessingYamlConfig -from pathopatcher.patch_extraction.patch_extraction import PreProcessor -from pathopatcher.utils.logger import Logger -from pathopatcher.utils.tools import close_logger +from pathopatch.cli import PreProcessingConfig, PreProcessingYamlConfig +from pathopatch.patch_extraction.patch_extraction import PreProcessor +from pathopatch.utils.logger import Logger +from pathopatch.utils.tools import close_logger from test_database.download import check_test_database diff --git a/tests/test_core_modules/test_downsample.py b/tests/test_core_modules/test_downsample.py index e4923fc..442cbcf 100644 --- a/tests/test_core_modules/test_downsample.py +++ b/tests/test_core_modules/test_downsample.py @@ -9,10 +9,10 @@ import yaml from PIL import Image -from pathopatcher.cli import PreProcessingConfig, PreProcessingYamlConfig -from pathopatcher.patch_extraction.patch_extraction import PreProcessor -from pathopatcher.utils.logger import Logger -from pathopatcher.utils.tools import close_logger +from pathopatch.cli import PreProcessingConfig, PreProcessingYamlConfig +from pathopatch.patch_extraction.patch_extraction import PreProcessor +from pathopatch.utils.logger import Logger +from pathopatch.utils.tools import close_logger from test_database.download import check_test_database diff --git a/tests/test_core_modules/test_roi.py b/tests/test_core_modules/test_roi.py index ad1e585..96d58fb 100644 --- a/tests/test_core_modules/test_roi.py +++ b/tests/test_core_modules/test_roi.py @@ -10,10 +10,10 @@ from numpy.testing import assert_almost_equal from PIL import Image -from pathopatcher.cli import PreProcessingConfig, PreProcessingYamlConfig -from pathopatcher.patch_extraction.patch_extraction import PreProcessor -from pathopatcher.utils.logger import Logger -from pathopatcher.utils.tools import close_logger +from pathopatch.cli import PreProcessingConfig, PreProcessingYamlConfig +from pathopatch.patch_extraction.patch_extraction import PreProcessor +from pathopatch.utils.logger import Logger +from pathopatch.utils.tools import close_logger from test_database.download import check_test_database diff --git a/tests/test_core_modules/test_roi_context.py b/tests/test_core_modules/test_roi_context.py index 8a15fa4..3ca49e4 100644 --- a/tests/test_core_modules/test_roi_context.py +++ b/tests/test_core_modules/test_roi_context.py @@ -10,10 +10,10 @@ from numpy.testing import assert_almost_equal from PIL import Image -from pathopatcher.cli import PreProcessingConfig, PreProcessingYamlConfig -from pathopatcher.patch_extraction.patch_extraction import PreProcessor -from pathopatcher.utils.logger import Logger -from pathopatcher.utils.tools import close_logger +from pathopatch.cli import PreProcessingConfig, PreProcessingYamlConfig +from pathopatch.patch_extraction.patch_extraction import PreProcessor +from pathopatch.utils.logger import Logger +from pathopatch.utils.tools import close_logger from test_database.download import check_test_database diff --git a/tests/test_core_modules/test_target_magnification.py b/tests/test_core_modules/test_target_magnification.py index 2563196..377a33e 100644 --- a/tests/test_core_modules/test_target_magnification.py +++ b/tests/test_core_modules/test_target_magnification.py @@ -5,10 +5,10 @@ from pathlib import Path import yaml -from pathopatcher.cli import PreProcessingConfig, PreProcessingYamlConfig -from pathopatcher.patch_extraction.patch_extraction import PreProcessor -from pathopatcher.utils.logger import Logger -from pathopatcher.utils.tools import close_logger +from pathopatch.cli import PreProcessingConfig, PreProcessingYamlConfig +from pathopatch.patch_extraction.patch_extraction import PreProcessor +from pathopatch.utils.logger import Logger +from pathopatch.utils.tools import close_logger from test_database.download import check_test_database diff --git a/tests/test_core_modules/test_target_mpp.py b/tests/test_core_modules/test_target_mpp.py index 5c928b6..4f564ec 100644 --- a/tests/test_core_modules/test_target_mpp.py +++ b/tests/test_core_modules/test_target_mpp.py @@ -6,10 +6,10 @@ import yaml -from pathopatcher.cli import PreProcessingConfig, PreProcessingYamlConfig -from pathopatcher.patch_extraction.patch_extraction import PreProcessor -from pathopatcher.utils.logger import Logger -from pathopatcher.utils.tools import close_logger +from pathopatch.cli import PreProcessingConfig, PreProcessingYamlConfig +from pathopatch.patch_extraction.patch_extraction import PreProcessor +from pathopatch.utils.logger import Logger +from pathopatch.utils.tools import close_logger from test_database.download import check_test_database diff --git a/tests/test_core_modules/test_target_mpp_macenko.py b/tests/test_core_modules/test_target_mpp_macenko.py index af35b2d..bc02598 100644 --- a/tests/test_core_modules/test_target_mpp_macenko.py +++ b/tests/test_core_modules/test_target_mpp_macenko.py @@ -8,10 +8,10 @@ from numpy.testing import assert_almost_equal from PIL import Image -from pathopatcher.cli import PreProcessingConfig, PreProcessingYamlConfig -from pathopatcher.patch_extraction.patch_extraction import PreProcessor -from pathopatcher.utils.logger import Logger -from pathopatcher.utils.tools import close_logger +from pathopatch.cli import PreProcessingConfig, PreProcessingYamlConfig +from pathopatch.patch_extraction.patch_extraction import PreProcessor +from pathopatch.utils.logger import Logger +from pathopatch.utils.tools import close_logger from test_database.download import check_test_database diff --git a/tests/test_macenko_module/test_macenko_loading.py b/tests/test_macenko_module/test_macenko_loading.py index bc1b460..83d6c7b 100644 --- a/tests/test_macenko_module/test_macenko_loading.py +++ b/tests/test_macenko_module/test_macenko_loading.py @@ -5,11 +5,11 @@ import yaml from numpy.testing import assert_array_equal -from pathopatcher.cli import ( +from pathopatch.cli import ( PreProcessingConfig, PreProcessingYamlConfig, ) -from pathopatcher.utils.patch_util import NormalizeParameters +from pathopatch.utils.patch_util import NormalizeParameters from test_database.download import check_test_database diff --git a/tests/test_macenko_module/test_macenko_saving.py b/tests/test_macenko_module/test_macenko_saving.py index 56408d7..990b1ca 100644 --- a/tests/test_macenko_module/test_macenko_saving.py +++ b/tests/test_macenko_module/test_macenko_saving.py @@ -9,8 +9,8 @@ import yaml from numpy.testing import assert_allclose -from pathopatcher.cli import MacenkoConfig, MacenkoParser, MacenkoYamlConfig -from pathopatcher.patch_extraction.patch_extraction import PreProcessor +from pathopatch.cli import MacenkoConfig, MacenkoParser, MacenkoYamlConfig +from pathopatch.patch_extraction.patch_extraction import PreProcessor from test_database.download import check_test_database diff --git a/tests/test_utils/test_csv_loading.py b/tests/test_utils/test_csv_loading.py index 569a627..22147a1 100644 --- a/tests/test_utils/test_csv_loading.py +++ b/tests/test_utils/test_csv_loading.py @@ -1,7 +1,7 @@ import unittest import pandas as pd from pathlib import Path -from pathopatcher.utils.file_handling import load_wsi_files_from_csv +from pathopatch.utils.file_handling import load_wsi_files_from_csv class TestLoadWSIFilesFromCSV(unittest.TestCase): diff --git a/tests/test_utils/test_mask_rgb.py b/tests/test_utils/test_mask_rgb.py index c18ae2a..dd853e1 100644 --- a/tests/test_utils/test_mask_rgb.py +++ b/tests/test_utils/test_mask_rgb.py @@ -1,6 +1,6 @@ import unittest import numpy as np -from pathopatcher.utils.masking import mask_rgb +from pathopatch.utils.masking import mask_rgb class TestMaskRGB(unittest.TestCase): From 7e7bb45b3e64877d22e2e3d9ade95382a611a560 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ho=CC=88rst?= Date: Fri, 12 Jan 2024 13:38:26 +0100 Subject: [PATCH 2/3] build: :green_heart: Adding setup for python build Adding setup for python build Building the package --- .gitignore | 12 ++- environment.yaml | 4 +- pathopatch/annotation_conversion.py | 2 + pathopatch/macenko_vector_generation.py | 15 +++- pathopatch/test_cli.py | 36 -------- pathopatch/wsi_extraction.py | 9 +- setup.py | 113 +++++++++++++----------- 7 files changed, 90 insertions(+), 101 deletions(-) delete mode 100644 pathopatch/test_cli.py diff --git a/.gitignore b/.gitignore index f639170..58b99de 100644 --- a/.gitignore +++ b/.gitignore @@ -12,11 +12,9 @@ notebooks # local configs .vscode -Tissue-Classifier-Data -tests_backup -tests/static_test_files/preprocessing/basic -tests/static_test_files/preprocessing/complex_annotation -tests/static_test_files/preprocessing/custom -tests/static_test_files/preprocessing/overlap tests/tmp_results_folder/* -output + +# Build +pathopatch.egg-info/ +dist +build diff --git a/environment.yaml b/environment.yaml index 1f302c8..7fda411 100644 --- a/environment.yaml +++ b/environment.yaml @@ -4,7 +4,7 @@ channels: - defaults dependencies: - python=3.10.12 - - openslide=3.4.1 + - openslide=4.0.0 - pip=23.0 - python-javabridge - pip: @@ -31,4 +31,4 @@ dependencies: - rasterio==1.3.5.post1 - scikit-image==0.19.3 - torchvision==0.16.2 - - tqdm==4.65.0 \ No newline at end of file + - tqdm==4.65.0 diff --git a/pathopatch/annotation_conversion.py b/pathopatch/annotation_conversion.py index 79c1c64..1d301bf 100644 --- a/pathopatch/annotation_conversion.py +++ b/pathopatch/annotation_conversion.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python + # -*- coding: utf-8 -*- # Geojson annotation preprocessing # diff --git a/pathopatch/macenko_vector_generation.py b/pathopatch/macenko_vector_generation.py index a90c7f8..621e9c2 100644 --- a/pathopatch/macenko_vector_generation.py +++ b/pathopatch/macenko_vector_generation.py @@ -1,4 +1,12 @@ +#!/usr/bin/env python + # -*- coding: utf-8 -*- +# Main entry point for Macenko +# +# @ Fabian Hörst, fabian.hoerst@uk-essen.de +# Institute for Artifical Intelligence in Medicine, +# University Medicine Essen + import inspect import logging import os @@ -18,7 +26,8 @@ from pathopatch.cli import MacenkoParser from pathopatch.patch_extraction.patch_extraction import PreProcessor -if __name__ == "__main__": + +def main(): configuration_parser = MacenkoParser() configuration, logger = configuration_parser.get_config() @@ -28,3 +37,7 @@ ) logger.info("Finished Macenko Vector Calculation!") + + +if __name__ == "__main__": + main() diff --git a/pathopatch/test_cli.py b/pathopatch/test_cli.py deleted file mode 100644 index eee1b5d..0000000 --- a/pathopatch/test_cli.py +++ /dev/null @@ -1,36 +0,0 @@ -# -*- coding: utf-8 -*- -# Geojson annotation preprocessing -# -# @ Fabian Hörst, fabian.hoerst@uk-essen.de -# Institute for Artifical Intelligence in Medicine, -# University Medicine Essen - -import os -import json -from tqdm import tqdm -import argparse -import uuid - -def main(): - parser = argparse.ArgumentParser( - description="Convert GeoJSON annotations (from QuPath) to JSON format." - ) - parser.add_argument( - "--input_folder", - type=str, - help="Path to the input folder containing GeoJSON files.", - ) - parser.add_argument( - "--output_folder", type=str, help="Path to the output folder for JSON files." - ) - parser.add_argument( - "--generate_tissue_outline", - action="store_true", - help="Generate tissue outline.", - ) - args = parser.parse_args() - print(args) - - -if __name__ == "__main__": - main() diff --git a/pathopatch/wsi_extraction.py b/pathopatch/wsi_extraction.py index 1bd0bc9..868804a 100644 --- a/pathopatch/wsi_extraction.py +++ b/pathopatch/wsi_extraction.py @@ -1,4 +1,4 @@ -# !/usr/bin/env python +#!/usr/bin/env python # -*- coding: utf-8 -*- # Main entry point for patch-preprocessing @@ -24,7 +24,8 @@ from pathopatch.patch_extraction.patch_extraction import PreProcessor from pathopatch.utils.tools import close_logger -if __name__ == "__main__": + +def main(): configuration_parser = PreProcessingParser() configuration, logger = configuration_parser.get_config() configuration_parser.store_config() @@ -34,3 +35,7 @@ logger.info("Finished Preprocessing.") close_logger(logger) + + +if __name__ == "__main__": + main() diff --git a/setup.py b/setup.py index b2472dc..c4a7729 100644 --- a/setup.py +++ b/setup.py @@ -1,60 +1,67 @@ -from setuptools import setup +from importlib.metadata import entry_points +from setuptools import find_packages, setup -VERSION = '2024.0.1a' -DESCRIPTION = 'PathoPatch - Accelerating Artificial Intelligence Based Whole Slide Image Analysis with an Optimized Preprocessing Pipeline' +VERSION = "2024.0.1a" +DESCRIPTION = "PathoPatch - Accelerating Artificial Intelligence Based Whole Slide Image Analysis with an Optimized Preprocessing Pipeline" with open("README.md", "r") as fh: LONG_DESCRIPTION = fh.read() # Setting up setup( - # the name must match the folder name 'verysimplemodule' - name="pathopatch", - version=VERSION, - author="Fabian Hörst", - author_email="fabian.hoerst@uk-essen.de", - description=DESCRIPTION, - long_description=LONG_DESCRIPTION, - url="https://github.com/TIO-IKIM/PathoPatcher", - long_description_content_type="text/markdown", - packages=["pathopatch"], - python_requires=">=3.9", - install_requires=[ - "Pillow>=9.5.0", - "PyYAML", - "Shapely==1.8.5.post1", - "colorama", - "future", - "geojson==3.0.0", - "histolab==0.6.0", - "matplotlib", - "natsort", - "numpy>1.22,<1.24", - "opencv_python_headless", - "openslide_python", - "pandas", - "pydantic==1.10.4", - "rasterio==1.3.5.post1", - "requests", - "scikit-image", - "setuptools<=65.6.3", - "tqdm", - "torchvision", - "torch" - ], - scripts=[ - "pathopatch/wsi_extraction.py", - "pathopatch/test_cli.py", - "pathopatch/annotation_conversion.py", - "pathopatch/macenko_vector_generation.py" + # the name must match the folder name 'verysimplemodule' + name="pathopatch", + version=VERSION, + author="Fabian Hörst", + author_email="fabian.hoerst@uk-essen.de", + description=DESCRIPTION, + long_description=LONG_DESCRIPTION, + url="https://github.com/TIO-IKIM/PathoPatcher", + long_description_content_type="text/markdown", + packages=find_packages(), + python_requires=">=3.9", + install_requires=[ + "Pillow>=9.5.0", + "PyYAML", + "Shapely==1.8.5.post1", + "colorama", + "future", + "geojson==3.0.0", + "histolab==0.6.0", + "matplotlib", + "natsort", + "numpy>1.22,<1.24", + "opencv_python_headless", + "openslide_python", + "pandas", + "pydantic==1.10.4", + "rasterio==1.3.5.post1", + "requests", + "scikit-image", + "setuptools<=65.6.3", + "tqdm", + "torchvision", + "torch", + ], + scripts=[ + "pathopatch/wsi_extraction.py", + "pathopatch/annotation_conversion.py", + "pathopatch/macenko_vector_generation.py", + ], + entry_points={ + "console_scripts": [ + "wsi_extraction=pathopatch.wsi_extraction:main", + "annotation_conversion=pathopatch.annotation_conversion:main", + "macenko_vector_generation=pathopatch.macenko_vector_generation:main", ], - keywords=["python", "pathopatch"], - classifiers= [ - "Development Status :: 3 - Alpha", - "Intended Audience :: Education", - "Topic :: Scientific/Engineering :: Artificial Intelligence", - "Programming Language :: Python :: 3", - "Operating System :: MacOS :: MacOS X", - "Operating System :: Microsoft :: Windows", - "Operating System :: POSIX :: Other" - ] -) \ No newline at end of file + }, + keywords=["python", "pathopatch"], + classifiers=[ + "Development Status :: 3 - Alpha", + "Intended Audience :: Education", + "Topic :: Scientific/Engineering :: Artificial Intelligence", + "Programming Language :: Python :: 3", + "Operating System :: MacOS :: MacOS X", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX :: Other", + ], +) From 2f63c32d224c0cf12bd3d899e11f3c2474b1c9a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ho=CC=88rst?= Date: Fri, 12 Jan 2024 13:39:46 +0100 Subject: [PATCH 3/3] build: :green_heart: Adding setup for python build Adding setup for python build Building the package --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index c4a7729..4cd06e3 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from importlib.metadata import entry_points from setuptools import find_packages, setup -VERSION = "2024.0.1a" +VERSION = "1.0.1b" DESCRIPTION = "PathoPatch - Accelerating Artificial Intelligence Based Whole Slide Image Analysis with an Optimized Preprocessing Pipeline" with open("README.md", "r") as fh: LONG_DESCRIPTION = fh.read()